From efe6913d6941242901b6e94ebf67baa0ea4b9e99 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Thu, 7 May 2026 11:17:55 +0800 Subject: [PATCH] Fix: Add exponential backoff to compute reconnection attempts When a remote compute is unreachable, the controller now uses exponential backoff for reconnection attempts: 5s, 10s, 20s, 40s, 80s, then caps at 300s (5 minutes). Previously it retried every 5 seconds indefinitely. User-initiated operations (open project, start node) still trigger an immediate connection attempt, so recovery is not delayed in practice. Related: #2704 --- gns3server/controller/compute.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index 9a9d94c29..c33cf5315 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -383,14 +383,16 @@ class Compute: if report_failed_connection: raise log.warning(f"Cannot connect to compute '{self._id}': {e}") - # Try to reconnect after 5 seconds if server unavailable only if not during tests (otherwise we create a ressource usage bomb) + # Try to reconnect if server unavailable only if not during tests (otherwise we create a ressource usage bomb) if not hasattr(sys, "_called_from_test") or not sys._called_from_test: self._connection_failure += 1 - # After 5 failure we close the project using the compute to avoid sync issues + # After 10 failures we close the project using the compute to avoid sync issues if self._connection_failure == 10: log.error(f"Could not connect to compute '{self._id}' after multiple attempts: {e}") await self._controller.close_compute_projects(self) - asyncio.get_event_loop().call_later(5, lambda: asyncio.ensure_future(self._try_reconnect())) + # Exponential backoff: 5s, 10s, 20s, 40s, 80s, then cap at 300s + delay = min(5 * (2 ** (self._connection_failure - 1)), 300) + asyncio.get_event_loop().call_later(delay, lambda: asyncio.ensure_future(self._try_reconnect())) return except web.HTTPNotFound: raise ControllerNotFoundError(f"The server {self._id} is not a GNS3 server or it's a 1.X server")