add full support for gevent. There is now 3 workers allowing us to use gunicorn with

gevent :
 - egg:gunicorn#gevent : gevent with gunicorn HTTP/WSGI parser
 - egg:gunicorn#gevent_wsgi : gevent.wsgi server
 - egg:gunicorn#gevent_pywsgi : gevent.pywsgi
This commit is contained in:
Benoit Chesneau 2010-07-14 23:45:44 +02:00
parent 40146dfe4f
commit 8014555636
3 changed files with 68 additions and 73 deletions

View File

@ -12,8 +12,20 @@ from gevent import monkey
monkey.noisy = False monkey.noisy = False
from gevent import greenlet from gevent import greenlet
from gevent.pool import Pool from gevent.pool import Pool
from gevent import pywsgi, wsgi
import gunicorn
from gunicorn.workers.async import AsyncWorker from gunicorn.workers.async import AsyncWorker
from gunicorn.workers.base import Worker
BASE_WSGI_ENV = {'GATEWAY_INTERFACE': 'CGI/1.1',
'SERVER_SOFTWARE': 'gevent/%s gunicorn/%s' % (gevent.__version__,
gunicorn.__version__),
'SCRIPT_NAME': '',
'wsgi.version': (1, 0),
'wsgi.multithread': False,
'wsgi.multiprocess': False,
'wsgi.run_once': False}
class GEventWorker(AsyncWorker): class GEventWorker(AsyncWorker):
@ -69,3 +81,57 @@ class GEventWorker(AsyncWorker):
pass pass
except Exception: except Exception:
self.log.exception("Unhandled exception in worker.") self.log.exception("Unhandled exception in worker.")
class WSGIHandler(wsgi.WSGIHandler):
def log_request(self, *args):
pass
class PyWSGIHandler(pywsgi.WSGIHandler):
def log_request(self, *args):
pass
class PyWSGIServer(pywsgi.WSGIServer):
base_env = BASE_WSGI_ENV
class WSGIServer(wsgi.WSGIServer):
base_env = BASE_WSGI_ENV
class GEventWSGIWorker(Worker):
server_class = WSGIServer
wsgi_handler = WSGIHandler
def __init__(self, *args, **kwargs):
super(GEventWSGIWorker, self).__init__(*args, **kwargs)
self.worker_connections = self.cfg.worker_connections
@classmethod
def setup(cls):
from gevent import monkey
monkey.patch_all(dns=False)
def run(self):
self.socket.setblocking(1)
pool = Pool(self.worker_connections)
server = self.server_class(self.socket, application=self.wsgi,
spawn=pool, handler_class=self.wsgi_handler)
server.start()
try:
while self.alive:
self.notify()
if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s" % self)
server.stop()
break
gevent.sleep(0.1)
self.pool.join(timeout=self.timeout)
except KeyboardInterrupt:
pass
class GEventPyWSGIWorker(GEventWSGIWorker):
server_class = PyWSGIServer
wsgi_handler = PyWSGIHandler

View File

@ -1,72 +0,0 @@
# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
import os
import gevent
from gevent import core
from gevent import monkey
monkey.noisy = False
from gevent.pool import Pool
from gevent import pywsgi
import gunicorn
from gunicorn.workers.base import Worker
class WSGIHandler(pywsgi.WSGIHandler):
def log_request(self, *args):
pass
class WSGIServer(pywsgi.WSGIServer):
base_env = {'GATEWAY_INTERFACE': 'CGI/1.1',
'SERVER_SOFTWARE': 'gevent/%s gunicorn/%s' % (gevent.__version__,
gunicorn.__version__),
'SCRIPT_NAME': '',
'wsgi.version': (1, 0),
'wsgi.multithread': False,
'wsgi.multiprocess': False,
'wsgi.run_once': False}
class GEvent2Worker(Worker):
def __init__(self, *args, **kwargs):
super(GEvent2Worker, self).__init__(*args, **kwargs)
self.worker_connections = self.cfg.worker_connections
@classmethod
def setup(cls):
from gevent import monkey
monkey.patch_all(dns=False)
def run(self):
self.socket.setblocking(1)
pool = Pool(self.worker_connections)
server = WSGIServer(self.socket, application=self.wsgi,
spawn=pool, handler_class=WSGIHandler)
server.start()
try:
while self.alive:
self.notify()
if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s" % self)
server.stop()
break
gevent.sleep(0.1)
self.pool.join(timeout=self.timeout)
except KeyboardInterrupt:
pass

View File

@ -54,7 +54,8 @@ setup(
sync=gunicorn.workers.sync:SyncWorker sync=gunicorn.workers.sync:SyncWorker
eventlet=gunicorn.workers.geventlet:EventletWorker eventlet=gunicorn.workers.geventlet:EventletWorker
gevent=gunicorn.workers.ggevent:GEventWorker gevent=gunicorn.workers.ggevent:GEventWorker
gevent2=gunicorn.workers.ggevent2:GEvent2Worker gevent_wsgi=gunicorn.workers.ggevent:GEventWSGIWorker
gevent_pywsgi=gunicorn.workers.ggevent:GEventPyWSGIWorker
tornado=gunicorn.workers.gtornado:TornadoWorker tornado=gunicorn.workers.gtornado:TornadoWorker
[paste.server_runner] [paste.server_runner]