From da637dfd13b520fc190b86967dfecc06bf97a2b4 Mon Sep 17 00:00:00 2001 From: benoitc Date: Mon, 4 Jun 2012 21:17:11 +0200 Subject: [PATCH] fix issue #348 . Rather than testing the parent pd, test if the parent pid is still alive. Only use it in gevent for now. --- .../testing/apps/someapp/middleware.py | 22 +++++++++++++++++++ .../django/testing/testing/settings.py | 1 + gunicorn/util.py | 7 ++++++ gunicorn/workers/ggevent.py | 7 ++++-- 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 examples/frameworks/django/testing/testing/apps/someapp/middleware.py diff --git a/examples/frameworks/django/testing/testing/apps/someapp/middleware.py b/examples/frameworks/django/testing/testing/apps/someapp/middleware.py new file mode 100644 index 00000000..a38ec5ac --- /dev/null +++ b/examples/frameworks/django/testing/testing/apps/someapp/middleware.py @@ -0,0 +1,22 @@ +from multiprocessing import Process, Queue +import requests + +def child_process(queue): + while True: + print queue.get() + r = requests.get('http://friendpaste.com') + print r.headers + +class GunicornSubProcessTestMiddleware(object): + def __init__(self): + super(GunicornSubProcessTestMiddleware, self).__init__() + self.queue = Queue() + self.process = Process(target=child_process, args=(self.queue,)) + self.process.start() + + def process_request(self, request): + self.queue.put(('REQUEST',)) + + def process_response(self, request, response): + self.queue.put(('RESPONSE',response.status_code)) + return response diff --git a/examples/frameworks/django/testing/testing/settings.py b/examples/frameworks/django/testing/testing/settings.py index cb8eca68..3a752c71 100644 --- a/examples/frameworks/django/testing/testing/settings.py +++ b/examples/frameworks/django/testing/testing/settings.py @@ -98,6 +98,7 @@ MIDDLEWARE_CLASSES = ( 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'testing.apps.someapp.middleware.GunicornSubProcessTestMiddleware' ) ROOT_URLCONF = 'testing.urls' diff --git a/gunicorn/util.py b/gunicorn/util.py index e919d53c..748ce2d6 100644 --- a/gunicorn/util.py +++ b/gunicorn/util.py @@ -353,3 +353,10 @@ def check_is_writeable(path): except IOError, e: raise RuntimeError("Error: '%s' isn't writable [%r]" % (path, e)) f.close() + +def is_process_running(process_id): + try: + os.kill(process_id, 0) + return True + except OSError: + return False diff --git a/gunicorn/workers/ggevent.py b/gunicorn/workers/ggevent.py index c92546c5..5b35bdc3 100644 --- a/gunicorn/workers/ggevent.py +++ b/gunicorn/workers/ggevent.py @@ -23,6 +23,7 @@ from gevent import pywsgi import gunicorn from gunicorn.workers.async import AsyncWorker +from gunicorn.util import is_process_running VERSION = "gevent/%s gunicorn/%s" % (gevent.__version__, gunicorn.__version__) @@ -36,6 +37,7 @@ BASE_WSGI_ENV = { 'wsgi.run_once': False } + class GeventWorker(AsyncWorker): server_class = None @@ -61,11 +63,12 @@ class GeventWorker(AsyncWorker): else: server = StreamServer(self.socket, handle=self.handle, spawn=pool) - server.start() + gevent.spawn(server.start) try: while self.alive: self.notify() - if self.ppid != os.getppid(): + + if not is_process_running(self.ppid): self.log.info("Parent changed, shutting down: %s", self) break