From d78fc46114a4ce1de505fc286798372ddaa0c32d Mon Sep 17 00:00:00 2001 From: oobabooga <112222186+oobabooga@users.noreply.github.com> Date: Sun, 5 Apr 2026 05:55:39 -0700 Subject: [PATCH] Fix "address already in use" on server restart (Linux/macOS) --- modules/api/script.py | 26 ++++++++++++++++++++++++-- modules/llama_cpp_server.py | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/modules/api/script.py b/modules/api/script.py index beed3d06..14e2d03a 100644 --- a/modules/api/script.py +++ b/modules/api/script.py @@ -591,9 +591,31 @@ def run_server(): if shared.args.admin_key and shared.args.admin_key != shared.args.api_key: logger.info(f'OpenAI API admin key (for loading/unloading models):\n\n{shared.args.admin_key}\n') - # Start server + # Use SO_REUSEADDR to avoid "address already in use" after restart logging.getLogger("uvicorn.error").propagate = False - uvicorn.run(app, host=server_addrs, port=port, ssl_certfile=ssl_certfile, ssl_keyfile=ssl_keyfile, access_log=False) + sockets = [] + try: + for addr in server_addrs: + family = socket.AF_INET6 if ':' in addr else socket.AF_INET + sock = socket.socket(family, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if family == socket.AF_INET6: + sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) + sock.bind((addr.strip('[]'), port)) + sock.listen(socket.SOMAXCONN) + sockets.append(sock) + except Exception: + for s in sockets: + s.close() + raise + + config = uvicorn.Config(app, ssl_certfile=ssl_certfile, ssl_keyfile=ssl_keyfile, access_log=False) + server = uvicorn.Server(config) + try: + server.run(sockets=sockets) + finally: + for s in sockets: + s.close() _server_started = False diff --git a/modules/llama_cpp_server.py b/modules/llama_cpp_server.py index 34080466..c01f5d5b 100644 --- a/modules/llama_cpp_server.py +++ b/modules/llama_cpp_server.py @@ -373,6 +373,7 @@ class LlamaServer: """Check if a port is available for use.""" with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: try: + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('', port)) return True except OSError: