mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
Merge pull request #786 from zeezooz/fix_signals
Change the rest of QUIT and TERM signals.
This commit is contained in:
commit
94f2cc03e1
@ -262,7 +262,7 @@ systemd:
|
|||||||
WorkingDirectory=/home/urban/gunicorn/bin
|
WorkingDirectory=/home/urban/gunicorn/bin
|
||||||
ExecStart=/home/someuser/gunicorn/bin/gunicorn -p /home/urban/gunicorn/gunicorn.pid- test:app
|
ExecStart=/home/someuser/gunicorn/bin/gunicorn -p /home/urban/gunicorn/gunicorn.pid- test:app
|
||||||
ExecReload=/bin/kill -s HUP $MAINPID
|
ExecReload=/bin/kill -s HUP $MAINPID
|
||||||
ExecStop=/bin/kill -s QUIT $MAINPID
|
ExecStop=/bin/kill -s TERM $MAINPID
|
||||||
PrivateTmp=true
|
PrivateTmp=true
|
||||||
|
|
||||||
**gunicorn.socket**::
|
**gunicorn.socket**::
|
||||||
|
|||||||
@ -727,7 +727,7 @@ worker_int
|
|||||||
def worker_int(worker):
|
def worker_int(worker):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
Called just after a worker exited on SIGINT or SIGTERM.
|
Called just after a worker exited on SIGINT or SIGQUIT.
|
||||||
|
|
||||||
The callable needs to accept one instance variable for the initialized
|
The callable needs to accept one instance variable for the initialized
|
||||||
Worker.
|
Worker.
|
||||||
|
|||||||
@ -22,7 +22,7 @@ Master process
|
|||||||
- **TTIN**: Increment the number of processes by one
|
- **TTIN**: Increment the number of processes by one
|
||||||
- **TTOU**: Decrement the nunber of processes by one
|
- **TTOU**: Decrement the nunber of processes by one
|
||||||
- **USR1**: Reopen the log files
|
- **USR1**: Reopen the log files
|
||||||
- **USR2**: Upgrade the Gunicorn on the fly. A separate **QUIT** signal should
|
- **USR2**: Upgrade the Gunicorn on the fly. A separate **TERM** signal should
|
||||||
be used to kill the old process. This signal can also be used to use the new
|
be used to kill the old process. This signal can also be used to use the new
|
||||||
versions of pre-loaded applications.
|
versions of pre-loaded applications.
|
||||||
- **WINCH**: Gracefully shutdown the worker processes when gunicorn is
|
- **WINCH**: Gracefully shutdown the worker processes when gunicorn is
|
||||||
@ -91,7 +91,7 @@ incoming requests together. To phase the old instance out, you have to
|
|||||||
send **WINCH** signal to the old master process, and its worker
|
send **WINCH** signal to the old master process, and its worker
|
||||||
processes will start to gracefully shut down.
|
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:
|
At 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 TERM 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
|
||||||
|
|||||||
@ -202,7 +202,7 @@ def when_ready(server):
|
|||||||
server.log.info("Server is ready. Spwawning workers")
|
server.log.info("Server is ready. Spwawning workers")
|
||||||
|
|
||||||
def worker_int(worker):
|
def worker_int(worker):
|
||||||
worker.log.info("worker received INT or TERM signal")
|
worker.log.info("worker received INT or QUIT signal")
|
||||||
|
|
||||||
## get traceback info
|
## get traceback info
|
||||||
import threading, sys, traceback
|
import threading, sys, traceback
|
||||||
|
|||||||
@ -29,7 +29,7 @@ class MemoryWatch(threading.Thread):
|
|||||||
if self.memory_usage(pid) > self.max_mem:
|
if self.memory_usage(pid) > self.max_mem:
|
||||||
self.server.log.info("Pid %s killed (memory usage > %s)",
|
self.server.log.info("Pid %s killed (memory usage > %s)",
|
||||||
pid, self.max_mem)
|
pid, self.max_mem)
|
||||||
self.server.kill_worker(pid, signal.SIGQUIT)
|
self.server.kill_worker(pid, signal.SIGTERM)
|
||||||
time.sleep(self.timeout)
|
time.sleep(self.timeout)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -229,7 +229,7 @@ class Arbiter(object):
|
|||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
def handle_quit(self):
|
def handle_quit(self):
|
||||||
"SIGTERM handling"
|
"SIGQUIT handling"
|
||||||
self.stop(False)
|
self.stop(False)
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
@ -273,7 +273,7 @@ class Arbiter(object):
|
|||||||
if self.cfg.daemon:
|
if self.cfg.daemon:
|
||||||
self.log.info("graceful stop of workers")
|
self.log.info("graceful stop of workers")
|
||||||
self.num_workers = 0
|
self.num_workers = 0
|
||||||
self.kill_workers(signal.SIGQUIT)
|
self.kill_workers(signal.SIGTERM)
|
||||||
else:
|
else:
|
||||||
self.log.debug("SIGWINCH ignored. Not daemonized")
|
self.log.debug("SIGWINCH ignored. Not daemonized")
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ class Arbiter(object):
|
|||||||
workers = sorted(workers, key=lambda w: w[1].age)
|
workers = sorted(workers, key=lambda w: w[1].age)
|
||||||
while len(workers) > self.num_workers:
|
while len(workers) > self.num_workers:
|
||||||
(pid, _) = workers.pop(0)
|
(pid, _) = workers.pop(0)
|
||||||
self.kill_worker(pid, signal.SIGQUIT)
|
self.kill_worker(pid, signal.SIGTERM)
|
||||||
|
|
||||||
def spawn_worker(self):
|
def spawn_worker(self):
|
||||||
self.worker_age += 1
|
self.worker_age += 1
|
||||||
|
|||||||
@ -1369,7 +1369,7 @@ class WorkerInt(Setting):
|
|||||||
|
|
||||||
default = staticmethod(worker_int)
|
default = staticmethod(worker_int)
|
||||||
desc = """\
|
desc = """\
|
||||||
Called just after a worker exited on SIGINT or SIGTERM.
|
Called just after a worker exited on SIGINT or SIGQUIT.
|
||||||
|
|
||||||
The callable needs to accept one instance variable for the initialized
|
The callable needs to accept one instance variable for the initialized
|
||||||
Worker.
|
Worker.
|
||||||
|
|||||||
@ -83,7 +83,7 @@ class Worker(object):
|
|||||||
if self.cfg.reload:
|
if self.cfg.reload:
|
||||||
def changed(fname):
|
def changed(fname):
|
||||||
self.log.info("Worker reloading: %s modified", fname)
|
self.log.info("Worker reloading: %s modified", fname)
|
||||||
os.kill(self.pid, signal.SIGTERM)
|
os.kill(self.pid, signal.SIGQUIT)
|
||||||
raise SystemExit()
|
raise SystemExit()
|
||||||
Reloader(callback=changed).start()
|
Reloader(callback=changed).start()
|
||||||
|
|
||||||
@ -130,10 +130,10 @@ class Worker(object):
|
|||||||
signal.signal(signal.SIGUSR1, self.handle_usr1)
|
signal.signal(signal.SIGUSR1, self.handle_usr1)
|
||||||
signal.signal(signal.SIGABRT, self.handle_abort)
|
signal.signal(signal.SIGABRT, self.handle_abort)
|
||||||
|
|
||||||
# Don't let SIGQUIT and SIGUSR1 disturb active requests
|
# Don't let SIGTERM and SIGUSR1 disturb active requests
|
||||||
# by interrupting system calls
|
# by interrupting system calls
|
||||||
if hasattr(signal, 'siginterrupt'): # python >= 2.6
|
if hasattr(signal, 'siginterrupt'): # python >= 2.6
|
||||||
signal.siginterrupt(signal.SIGQUIT, False)
|
signal.siginterrupt(signal.SIGTERM, False)
|
||||||
signal.siginterrupt(signal.SIGUSR1, False)
|
signal.siginterrupt(signal.SIGUSR1, False)
|
||||||
|
|
||||||
def handle_usr1(self, sig, frame):
|
def handle_usr1(self, sig, frame):
|
||||||
@ -141,11 +141,11 @@ class Worker(object):
|
|||||||
|
|
||||||
def handle_exit(self, sig, frame):
|
def handle_exit(self, sig, frame):
|
||||||
self.alive = False
|
self.alive = False
|
||||||
# worker_int callback
|
|
||||||
self.cfg.worker_int(self)
|
|
||||||
|
|
||||||
def handle_quit(self, sig, frame):
|
def handle_quit(self, sig, frame):
|
||||||
self.alive = False
|
self.alive = False
|
||||||
|
# worker_int callback
|
||||||
|
self.cfg.worker_int(self)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def handle_abort(self, sig, frame):
|
def handle_abort(self, sig, frame):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user