{"record":{"id":"b5369c05c5ba9fb3","repo":"XX-net/XX-Net","slug":"stopping-conn-d-fail-r","errorCode":null,"errorMessage":"stopping conn:%d fail:%r","messagePattern":"stopping conn:(.+?) fail:%r","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/x_tunnel/local/proxy_session.py","lineNumber":510,"sourceCode":"\n        self.target_on_roads = \\\n            min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + 2)\n        self.trigger_more()\n\n        if log:\n            xlog.info(\"Connect to %s:%d conn:%d\", host, port, conn_id)\n        return conn_id\n\n    # Called by stop\n    def close_all_connection(self):\n        xlog.info(\"start close all connection\")\n        conn_list = dict(self.conn_list)\n        for conn_id in conn_list:\n            try:\n                # xlog.debug(\"stopping conn:%d\", conn_id)\n                self.conn_list[conn_id].stop(reason=\"system reset\")\n            except Exception as e:\n                xlog.warn(\"stopping conn:%d fail:%r\", conn_id, e)\n                pass\n        # self.conn_list = {}\n        xlog.debug(\"stop all connection finished\")\n\n    def remove_conn(self, conn_id):\n        try:\n            if conn_id in self.conn_list:\n                conn = self.conn_list[conn_id]\n                # xlog.debug(\"remove conn:%d %s:%d\", conn_id, conn.host, conn.port)\n                del self.conn_list[conn_id]\n        except Exception as e:\n            xlog.warn(\"remove conn:%d except:%r\", conn_id, e)\n\n        if len(self.conn_list) == 0:\n            self.target_on_roads = 0\n\n    def send_conn_data(self, conn_id, data):\n        if not self.running:","sourceCodeStart":492,"sourceCodeEnd":528,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/x_tunnel/local/proxy_session.py#L492-L528","documentation":"During session stop, close_all_connection iterates every conn in conn_list and calls conn.stop(reason='system reset'); if an individual connection's stop() raises, the exception is caught per-connection and logged with the conn_id and the exception repr, so one bad connection cannot abort shutting down the rest.","triggerScenarios":"Shutting down / restarting the x-tunnel session while some connection objects are in an inconsistent state (e.g. already-closed socket, error during buffered-write flush in stop()).","commonSituations":"Restarting the tunnel after network errors; stop racing with a connection whose underlying socket errored concurrently; version upgrades changing connection state fields that stop() expects.","solutions":["This is handled gracefully — shutdown proceeds; no action needed unless connections leak.","Check the exception repr in the log to identify which stop() path raised and whether connections are actually cleaned up.","If connections leak (fd exhaustion), upgrade x_tunnel / patch the connection stop() to be idempotent.","Avoid triggering stop() concurrently from multiple threads; call session.stop() once."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"# per-item catch during mass shutdown\nfor conn_id in list(session.conn_list):\n    try:\n        session.conn_list[conn_id].stop(reason='shutdown')\n    except Exception as e:\n        logger.warning('stop conn %s failed: %r', conn_id, e)","preventionTips":["Call session.stop() once, from one thread.","Monitor open fd/socket counts after shutdown to detect leaks.","Upgrade x_tunnel if stop() exceptions recur — later versions make stop idempotent."],"tags":["shutdown","lifecycle","connection-cleanup"],"backgroundTag":"cleanup-on-shutdown-failed","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}