[FIX] server: support for systemd socket activation in threaded server

This patches fixes the untested and broken draft of inetd and systemd
activation support in the threaded server.

This patch also introduces a change of behaviour in the `_reexec()`
function by keeping the environment when Odoo is respawning during the
following events:

    - SIGHUP signal is received
    - one click install has been triggered
    - code reload needed when using `--dev=reload`
This commit is contained in:
Fabien Meghazi
2018-03-09 09:03:58 +01:00
parent b17ba359db
commit 985bb12488
+5 -8
View File
@@ -92,9 +92,6 @@ class RequestHandler(werkzeug.serving.WSGIRequestHandler):
me = threading.currentThread()
me.name = 'odoo.service.http.request.%s' % (me.ident,)
# _reexec() should set LISTEN_* to avoid connection refused during reload time. It
# should also work with systemd socket activation. This is currently untested
# and not yet used.
class ThreadedWSGIServerReloadable(LoggingBaseWSGIServerMixIn, werkzeug.serving.ThreadedWSGIServer):
""" werkzeug Threaded WSGI Server patched to allow reusing a listen socket
@@ -106,11 +103,10 @@ class ThreadedWSGIServerReloadable(LoggingBaseWSGIServerMixIn, werkzeug.serving.
handler=RequestHandler)
def server_bind(self):
envfd = os.environ.get('LISTEN_FDS')
if envfd and os.environ.get('LISTEN_PID') == str(os.getpid()):
SD_LISTEN_FDS_START = 3
if os.environ.get('LISTEN_FDS') == '1' and os.environ.get('LISTEN_PID') == str(os.getpid()):
self.reload_socket = True
self.socket = socket.fromfd(int(envfd), socket.AF_INET, socket.SOCK_STREAM)
# should we os.close(int(envfd)) ? it seem python duplicate the fd.
self.socket = socket.fromfd(SD_LISTEN_FDS_START, socket.AF_INET, socket.SOCK_STREAM)
else:
self.reload_socket = False
super(ThreadedWSGIServerReloadable, self).server_bind()
@@ -883,7 +879,8 @@ def _reexec(updated_modules=None):
args += ["-u", ','.join(updated_modules)]
if not args or args[0] != exe:
args.insert(0, exe)
os.execv(sys.executable, args)
# We should keep the LISTEN_* environment variabled in order to support socket activation on reexec
os.execve(sys.executable, args, os.environ)
def load_test_file_py(registry, test_file):
# Locate python module based on its filename and run the tests