Release v0.51.280 — Release IV (stage-p3i — Windows self-update restart fix #3647) (#3687)
Some checks failed
Release & Docker / release (push) Has been cancelled
Some checks failed
Release & Docker / release (push) Has been cancelled
* fix(updates): Windows self-update restart via detached Popen + bind-retry (os.execv doesn't replace proc on Windows) (#3647) Co-authored-by: jja881 <jja881@users.noreply.github.com> * docs(changelog): v0.51.280 — Release IV (stage-p3i) --------- Co-authored-by: nesquena-hermes <[email protected]> Co-authored-by: jja881 <jja881@users.noreply.github.com>
This commit is contained in:
19
server.py
19
server.py
@@ -210,7 +210,24 @@ class QuietHTTPServer(ThreadingHTTPServer):
|
||||
self.allow_reuse_address = False
|
||||
SO_EXCLUSIVEADDRUSE = getattr(socket, 'SO_EXCLUSIVEADDRUSE', -5)
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1)
|
||||
super().server_bind()
|
||||
# Retry bind on Windows to handle the case where a previous
|
||||
# process (e.g. during self-update) is still releasing the port.
|
||||
# The old process calls os._exit(0) which starts tearing down
|
||||
# its socket, but with SO_EXCLUSIVEADDRUSE the OS blocks new
|
||||
# binds until the teardown completes. Retry for up to 10 s.
|
||||
max_retries = 20
|
||||
retry_delay = 0.5
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
super().server_bind()
|
||||
return
|
||||
except OSError as e:
|
||||
if e.winerror == 10048 and attempt < max_retries - 1: # WSAEADDRINUSE
|
||||
time.sleep(retry_delay)
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
super().server_bind()
|
||||
|
||||
def _handle_request_noblock(self):
|
||||
"""Record accept-loop progress before dispatching a request handler.
|
||||
|
||||
Reference in New Issue
Block a user