diff --git a/gunicorn/workers/gtornado.py b/gunicorn/workers/gtornado.py index 79665856..b7416305 100644 --- a/gunicorn/workers/gtornado.py +++ b/gunicorn/workers/gtornado.py @@ -31,15 +31,16 @@ class TornadoWorker(Worker): sys.modules["tornado.web"] = web def handle_quit(self, sig, frame): - super(TornadoWorker, self).handle_quit(sig, frame) - self.ioloop.stop() + if self.alive: + super(TornadoWorker, self).handle_quit(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.ioloop.stop() + self.stop() def watchdog(self): if self.alive: @@ -47,7 +48,7 @@ class TornadoWorker(Worker): if self.ppid != os.getppid(): self.log.info("Parent changed, shutting down: %s", self) - self.ioloop.stop() + self.stop() def run(self): self.ioloop = IOLoop.instance() @@ -82,6 +83,8 @@ class TornadoWorker(Worker): server = tornado.httpserver.HTTPServer(app, io_loop=self.ioloop) + self.server = server + for s in self.sockets: s.setblocking(0) if hasattr(server, "add_socket"): # tornado > 2.0 @@ -94,3 +97,15 @@ class TornadoWorker(Worker): 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()