mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
switch QUIT and TERM signal
With this change, when gunicorn receives a QUIT all the workers are killed immediately and exit and TERM is used for the graceful shutdown. Note: the old behaviour was based on the NGINX but the new one is more correct according the following doc: https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html also it is complying with the way the signals are sent by heroku: https://devcenter.heroku.com/articles/python-faq#what-constraints-exist-when-developing-applications-on-heroku
This commit is contained in:
parent
24a060ed02
commit
81241907ff
@ -12,8 +12,8 @@ exception of TTIN/TTOU the signals handling match the behaviour of `nginx
|
|||||||
Master process
|
Master process
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- **TERM**, **INT**: Quick shutdown
|
- **QUIT**, **INT**: Quick shutdown
|
||||||
- **QUIT**: Graceful shutdown. Waits for workers to finish their
|
- **TERM**: Graceful shutdown. Waits for workers to finish their
|
||||||
current requests up to the *graceful timeout*.
|
current requests up to the *graceful timeout*.
|
||||||
- **HUP**: Reload the configuration, start the new worker processes with a new
|
- **HUP**: Reload the configuration, start the new worker processes with a new
|
||||||
configuration and gracefully shutdown older workers. If the application is
|
configuration and gracefully shutdown older workers. If the application is
|
||||||
@ -35,8 +35,8 @@ Sending signals directly to the worker processes should not normally be
|
|||||||
needed. If the master process is running, any exited worker will be
|
needed. If the master process is running, any exited worker will be
|
||||||
automatically respawned.
|
automatically respawned.
|
||||||
|
|
||||||
- **TERM**, **INT**: Quick shutdown
|
- **QUIT**, **INT**: Graceful shutdown
|
||||||
- **QUIT**: Graceful shutdown
|
- **TERM**: Quick shutdown
|
||||||
- **USR1**: Reopen the log files
|
- **USR1**: Reopen the log files
|
||||||
|
|
||||||
Reload the configuration
|
Reload the configuration
|
||||||
@ -94,16 +94,16 @@ processes will start to gracefully shut down.
|
|||||||
t this point you can still revert to the old server because it hasn't closed its listen sockets yet, by following these steps:
|
t this point you can still revert to the old server because it hasn't closed its listen sockets yet, by following these steps:
|
||||||
|
|
||||||
- Send HUP signal to the old master process - it will start the worker processes without reloading a configuration file
|
- Send HUP signal to the old master process - it will start the worker processes without reloading a configuration file
|
||||||
- Send QUIT signal to the new master process to gracefully shut down its worker processes
|
- Send TERM signal to the new master process to gracefully shut down its worker processes
|
||||||
- Send TERM signal to the new master process to force it quit
|
- Send QUIT signal to the new master process to force it quit
|
||||||
|
|
||||||
If for some reason new worker processes do not quit, send KILL signal to
|
If for some reason new worker processes do not quit, send KILL signal to
|
||||||
them After new master process quits, the old master process removes
|
them after the new master process quits, the old master process removes
|
||||||
.oldbin suffix from its .pid file, and everything is exactly as before
|
.oldbin suffix from its .pid file, and everything is exactly as before
|
||||||
the upgrade attempt.
|
the upgrade attempt.
|
||||||
|
|
||||||
If an update is successful and you want to keep the new server, send
|
If an update is successful and you want to keep the new server, send
|
||||||
QUIT signal to the old master process to leave only new server
|
the TERM signal to the old master process to leave only new server
|
||||||
running::
|
running::
|
||||||
|
|
||||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||||
|
|||||||
@ -222,8 +222,8 @@ class Arbiter(object):
|
|||||||
self.log.info("Hang up: %s", self.master_name)
|
self.log.info("Hang up: %s", self.master_name)
|
||||||
self.reload()
|
self.reload()
|
||||||
|
|
||||||
def handle_quit(self):
|
def handle_term(self):
|
||||||
"SIGQUIT handling"
|
"SIGTERM handling"
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
def handle_int(self):
|
def handle_int(self):
|
||||||
@ -231,7 +231,7 @@ class Arbiter(object):
|
|||||||
self.stop(False)
|
self.stop(False)
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
def handle_term(self):
|
def handle_quit(self):
|
||||||
"SIGTERM handling"
|
"SIGTERM handling"
|
||||||
self.stop(False)
|
self.stop(False)
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|||||||
@ -125,7 +125,7 @@ class Worker(object):
|
|||||||
# init new signaling
|
# init new signaling
|
||||||
signal.signal(signal.SIGQUIT, self.handle_quit)
|
signal.signal(signal.SIGQUIT, self.handle_quit)
|
||||||
signal.signal(signal.SIGTERM, self.handle_exit)
|
signal.signal(signal.SIGTERM, self.handle_exit)
|
||||||
signal.signal(signal.SIGINT, self.handle_exit)
|
signal.signal(signal.SIGINT, self.handle_quit)
|
||||||
signal.signal(signal.SIGWINCH, self.handle_winch)
|
signal.signal(signal.SIGWINCH, self.handle_winch)
|
||||||
signal.signal(signal.SIGUSR1, self.handle_usr1)
|
signal.signal(signal.SIGUSR1, self.handle_usr1)
|
||||||
# Don't let SIGQUIT and SIGUSR1 disturb active requests
|
# Don't let SIGQUIT and SIGUSR1 disturb active requests
|
||||||
@ -137,13 +137,13 @@ class Worker(object):
|
|||||||
def handle_usr1(self, sig, frame):
|
def handle_usr1(self, sig, frame):
|
||||||
self.log.reopen_files()
|
self.log.reopen_files()
|
||||||
|
|
||||||
def handle_quit(self, sig, frame):
|
|
||||||
self.alive = False
|
|
||||||
|
|
||||||
def handle_exit(self, sig, frame):
|
def handle_exit(self, sig, frame):
|
||||||
self.alive = False
|
self.alive = False
|
||||||
# worker_int callback
|
# worker_int callback
|
||||||
self.cfg.worker_int(self)
|
self.cfg.worker_int(self)
|
||||||
|
|
||||||
|
def handle_quit(self, sig, frame):
|
||||||
|
self.alive = False
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def handle_error(self, req, client, addr, exc):
|
def handle_error(self, req, client, addr, exc):
|
||||||
|
|||||||
@ -30,9 +30,9 @@ class TornadoWorker(Worker):
|
|||||||
web.RequestHandler.clear = clear
|
web.RequestHandler.clear = clear
|
||||||
sys.modules["tornado.web"] = web
|
sys.modules["tornado.web"] = web
|
||||||
|
|
||||||
def handle_quit(self, sig, frame):
|
def handle_exit(self, sig, frame):
|
||||||
if self.alive:
|
if self.alive:
|
||||||
super(TornadoWorker, self).handle_quit(sig, frame)
|
super(TornadoWorker, self).handle_exit(sig, frame)
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
def handle_request(self):
|
def handle_request(self):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user