Skip to content

Commit

Permalink
make graceful shutdown thread-safe
Browse files Browse the repository at this point in the history
  • Loading branch information
陈程龙 committed May 23, 2015
1 parent cc7459d commit 29080f4
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions gunicorn/workers/gtornado.py
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
Expand Down Expand Up @@ -33,27 +32,40 @@ def clear(self):
def handle_exit(self, sig, frame):
if self.alive:
super(TornadoWorker, self).handle_exit(sig, frame)
self.stop()

def handle_request(self):
self.nr += 1
if self.alive and self.nr >= self.max_requests:
self.alive = False
self.log.info("Autorestarting worker after current request.")
self.stop()
self.alive = False

def watchdog(self):
if self.alive:
self.notify()

if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s", self)
self.stop()
self.alive = False

def heartbeat(self):
if not self.alive:
if self.server_alive:
if hasattr(self, 'server'):
try:
self.server.stop()
except Exception:
pass
self.server_alive = False
else:
if not self.ioloop._callbacks and len(self.ioloop._timeouts) <= 1:
self.ioloop.stop()

def run(self):
self.ioloop = IOLoop.instance()
self.alive = True
self.server_alive = False
PeriodicCallback(self.watchdog, 1000, io_loop=self.ioloop).start()
PeriodicCallback(self.heartbeat, 1000, io_loop=self.ioloop).start()

# Assume the app is a WSGI callable if its not an
# instance of tornado.web.Application or is an
Expand Down Expand Up @@ -95,6 +107,7 @@ def on_close(instance, server_conn):
server = server_class(app, io_loop=self.ioloop)

self.server = server
self.server_alive = True

for s in self.sockets:
s.setblocking(0)
Expand All @@ -107,15 +120,3 @@ def on_close(instance, server_conn):
server.start(num_processes=1)

self.ioloop.start()

def stop(self):
if hasattr(self, 'server'):
try:
self.server.stop()
except Exception:
pass
PeriodicCallback(self.stop_ioloop, 1000, io_loop=self.ioloop).start()

def stop_ioloop(self):
if not self.ioloop._callbacks and len(self.ioloop._timeouts) <= 1:
self.ioloop.stop()

0 comments on commit 29080f4

Please sign in to comment.