Set SO_REUSEADDR and SO_REUSEPORT to enable faster service restarts

In a fast restart of the service we don't have time for all the TCP
sessions to drain the sockets in TIME_WAIT.  So the service fails to
restart with a "bind address in use".   To avoid this we want to add
SO_REUSEADDR and SO_REUSEPORT.  To do so we have to disable
bind_and_activate so we can then set allow_reuse_address and
allow_reuse_address on the TCPServer before we bind.

For reference:
 * https://docs.python.org/3/library/socketserver.html#socketserver.BaseServer.allow_reuse_address
 * https://github.com/python/cpython/blob/3.11/Lib/socketserver.py#L445
 * https://github.com/python/cpython/blob/3.11/Lib/socketserver.py#L447

Change-Id: I2ecbedf43e9912d430197e4110e4d467a8b449a3
This commit is contained in:
Tony Breeds 2023-10-04 12:24:43 +11:00
parent d01468e188
commit 287f8d5063

View File

@ -41,7 +41,18 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
def start(): def start():
os.chdir(CONFIG['source_dir']) os.chdir(CONFIG['source_dir'])
with socketserver.TCPServer(("", CONFIG['port']), RequestHandler) as httpd: # In a fast restart of the service we don't have time for all the TCP
# sessions to drain the sockets in TIME_WAIT. So the service fails to
# restart with a "bind address in use". To avoid this we want to add
# SO_REUSEADDR and SO_REUSEPORT. To do so we have to disable
# bind_and_activate so we can then set allow_reuse_address and
# allow_reuse_address on the TCPServer before we bind.
with socketserver.TCPServer(("", CONFIG['port']), RequestHandler,
bind_and_activate=False) as httpd:
httpd.allow_reuse_address = True
httpd.allow_reuse_port = True
httpd.server_bind()
httpd.server_activate()
httpd.serve_forever() httpd.serve_forever()