fix: set SO_REUSEADDR on port pre-check so restarts don't wait for TIME_WAIT

The fail-fast port check bound a plain socket, so TIME_WAIT sockets left
by a just-stopped instance (~60s) made it report 'port already in use'
even though uvicorn (which sets SO_REUSEADDR) could bind fine. Mirror
uvicorn's bind semantics: the check now only fails when the port is
genuinely held by a live listener.
This commit is contained in:
ARIA committed 2026-10-03 21:18:22 +02:00
1 parent 3c0fee3ec8
commit 5cfadb4d9b
1 file changed
+4
+4
View File
@@ -2610,7 +2610,11 @@ def run(
# Fail fast if the port is already in use — silently shifting ports breaks # Fail fast if the port is already in use — silently shifting ports breaks
# client discovery. Users should configure a different port explicitly. # client discovery. Users should configure a different port explicitly.
# SO_REUSEADDR mirrors uvicorn's own bind: without it, TIME_WAIT sockets
# left by a just-stopped instance (~60s) would fail this check even though
# uvicorn could bind fine, forcing a wait on every restart.
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try: try:
s.bind((host, port)) s.bind((host, port))
except OSError: except OSError: