From b9bb3453c25af3b746894711e1e11c9c82c4e01d Mon Sep 17 00:00:00 2001 From: Konstantin Kapustin Date: Wed, 25 Jul 2012 17:26:52 +0400 Subject: [PATCH] Fix graceful shutdown for gevent. server.stop() are blocking worker and which is then may be killed by Arbiter.murder_workers() with timeout (not graceful_timeout). It's issues when graceful_timeout > timeout. --- gunicorn/workers/ggevent.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/gunicorn/workers/ggevent.py b/gunicorn/workers/ggevent.py index 3c080862..b89cd4c2 100644 --- a/gunicorn/workers/ggevent.py +++ b/gunicorn/workers/ggevent.py @@ -8,6 +8,7 @@ from __future__ import with_statement import os import sys from datetime import datetime +import time # workaround on osx, disable kqueue if sys.platform == "darwin": @@ -77,9 +78,21 @@ class GeventWorker(AsyncWorker): pass try: - # Try to stop connections until timeout - self.notify() - server.stop(timeout=self.cfg.graceful_timeout) + # Stop accepting requests + server.kill() + + # Handle current requests until graceful_timeout + ts = time.time() + while time.time() - ts <= self.cfg.graceful_timeout: + if server.pool.free_count() == server.pool.size: + return # all requests was handled + + self.notify() + gevent.sleep(1.0) + + # Force kill all active the handlers + self.log.warning("Worker graceful timeout (pid:%s)" % self.pid) + server.stop(timeout=1) except: pass