From 506b0b9f4a8b489fb133db1b99527711bc436564 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Mon, 10 Aug 2026 23:00:59 +0800 Subject: [PATCH] perf: enable TCP keep-alive for local compute HTTP requests When controller and compute share the same process, every HTTP request to localhost was paying a full TCP handshake (force_close=True forced connection teardown after each request). With 2500+ links each sending two NIO POSTs, that's 5000 SYN->SYN-ACK->ACK cycles even for sub-ms in-memory handlers. Switch to keep-alive for loopback compute (127.0.0.1 / ::1 / localhost) while keeping force_close for remote computes that may sit behind NAT/firewalls that drop idle connections. --- gns3server/controller/compute.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py index 7ec8691a8..d32a1a84a 100644 --- a/gns3server/controller/compute.py +++ b/gns3server/controller/compute.py @@ -102,7 +102,13 @@ class Compute: def _session(self): if self._http_session is None or self._http_session.closed is True: - connector = aiohttp.TCPConnector(force_close=True, ssl_context=self._ssl_context) + # Reuse TCP keep-alive for local compute (loopback) to avoid paying + # a TCP handshake on every HTTP request; force-close for remote + # computes in case intermediate firewalls/NATs drop idle connections. + _local = self._host in ("127.0.0.1", "::1", "localhost") + connector = aiohttp.TCPConnector( + force_close=not _local, ssl_context=self._ssl_context + ) self._http_session = aiohttp.ClientSession(connector=connector) return self._http_session