← Commit history

v0.9.1: single-instance guard

John Lauer ·aceb0722f0 ·3mo ago ·parent f46970d
1 file changed +22−2
server.py+22−2
@@ -396,6 +396,26 @@ def main():         if idx + 1 < len(sys.argv):             port = int(sys.argv[idx + 1]) +    # ── SINGLE-INSTANCE GUARD ────────────────────────────────────────────────+    # Bind the port FIRST, before the (slow ~9s) KiCad detection. A supervisor+    # that lazy-spawns the bridge on every verb call can otherwise fire several+    # instances near-simultaneously; if they all run detection before binding,+    # they contend (KiCad config/IPC probes) and HANG, none ever binds, and the+    # bridge never reports healthy — a spawn storm. Binding first makes exactly+    # ONE spawn win the port; every duplicate fails the bind and exits cleanly+    # (exit 0) instead of piling up. allow_reuse_address is forced False so the+    # second bind genuinely fails on Windows (SO_REUSEADDR would otherwise let+    # duplicates co-bind). This keeps the bridge robust no matter how aggressive+    # the host's spawn logic is.+    class _SingleInstanceHTTPServer(HTTPServer):+        allow_reuse_address = False+    try:+        server = _SingleInstanceHTTPServer(("127.0.0.1", port), KiCadBridgeHandler)+    except OSError as e:+        print(f"[KiCad Bridge] Port {port} already in use ({e}). "+              f"Another bridge instance owns it — exiting cleanly (single-instance guard).")+        return+     all_kicad_versions = detect_all_kicad_versions()     kicad_info = all_kicad_versions[0] if all_kicad_versions else detect_kicad() @@ -424,9 +444,9 @@ def main():         symbols = lib_result.get("symbols", [])         print(f"[KiCad Bridge] Adom library: {len(symbols)} symbol(s) — {', '.join(symbols) if symbols else '(empty)'}") -    server = HTTPServer(("127.0.0.1", port), KiCadBridgeHandler)+    # server already bound above (single-instance guard); now serve.     print(f"[KiCad Bridge] Listening on http://127.0.0.1:{port}")-    print(f"[KiCad Bridge] Health check: http://127.0.0.1:{port}/health")+    print(f"[KiCad Bridge] Health check: http://127.0.0.1:{port}/status (and /health)")     print(f"[KiCad Bridge] Press Ctrl+C to stop.")      try: