Bump minimum Eventlet and Gevent versions (#1962)

Update the Eventlet and Gevent worker classes to check for versions of
Eventlet and Gevent that are stable under Python 3 and remove outdated
compatibility code.
This commit is contained in:
Randall Leeds 2019-01-24 23:24:14 -08:00 committed by Benoit Chesneau
parent fe7632fe37
commit 9f87c88819
3 changed files with 24 additions and 56 deletions

View File

@ -630,9 +630,9 @@ class WorkerClass(Setting):
A string referring to one of the following bundled classes: A string referring to one of the following bundled classes:
* ``sync`` * ``sync``
* ``eventlet`` - Requires eventlet >= 0.9.7 (or install it via * ``eventlet`` - Requires eventlet >= 0.24 (or install it via
``pip install gunicorn[eventlet]``) ``pip install gunicorn[eventlet]``)
* ``gevent`` - Requires gevent >= 0.13 (or install it via * ``gevent`` - Requires gevent >= 1.4 (or install it via
``pip install gunicorn[gevent]``) ``pip install gunicorn[gevent]``)
* ``tornado`` - Requires tornado >= 0.2 (or install it via * ``tornado`` - Requires tornado >= 0.2 (or install it via
``pip install gunicorn[tornado]``) ``pip install gunicorn[tornado]``)

View File

@ -11,12 +11,11 @@ import sys
try: try:
import eventlet import eventlet
except ImportError: except ImportError:
raise RuntimeError("You need eventlet installed to use this worker.") raise RuntimeError("eventlet worker requires eventlet 0.24 or higher")
else:
# validate the eventlet version from pkg_resources import parse_version
if eventlet.version_info < (0, 9, 7): if parse_version(eventlet.__version__) < parse_version('0.24'):
raise RuntimeError("You need eventlet >= 0.9.7") raise RuntimeError("eventlet worker requires eventlet 0.24 or higher")
from eventlet import hubs, greenthread from eventlet import hubs, greenthread
from eventlet.greenio import GreenSocket from eventlet.greenio import GreenSocket
@ -26,6 +25,7 @@ import greenlet
from gunicorn.workers.base_async import AsyncWorker from gunicorn.workers.base_async import AsyncWorker
def _eventlet_sendfile(fdout, fdin, offset, nbytes): def _eventlet_sendfile(fdout, fdin, offset, nbytes):
while True: while True:
try: try:
@ -86,7 +86,7 @@ class EventletWorker(AsyncWorker):
def patch(self): def patch(self):
hubs.use_hub() hubs.use_hub()
eventlet.monkey_patch(os=False) eventlet.monkey_patch()
patch_sendfile() patch_sendfile()
def is_already_handled(self, respiter): def is_already_handled(self, respiter):

View File

@ -10,20 +10,18 @@ from datetime import datetime
from functools import partial from functools import partial
import time import time
_socket = __import__("socket")
# workaround on osx, disable kqueue
if sys.platform == "darwin":
os.environ['EVENT_NOKQUEUE'] = "1"
try: try:
import gevent import gevent
except ImportError: except ImportError:
raise RuntimeError("You need gevent installed to use this worker.") raise RuntimeError("gevent worker requires gevent 1.4 or higher")
else:
from pkg_resources import parse_version
if parse_version(gevent.__version__) < parse_version('1.4'):
raise RuntimeError("gevent worker requires gevent 1.4 or higher")
from gevent.pool import Pool from gevent.pool import Pool
from gevent.server import StreamServer from gevent.server import StreamServer
from gevent.socket import wait_write, socket from gevent import hub, monkey, socket, pywsgi
from gevent import pywsgi
import gunicorn import gunicorn
from gunicorn.http.wsgi import base_environ from gunicorn.http.wsgi import base_environ
@ -31,13 +29,14 @@ from gunicorn.workers.base_async import AsyncWorker
VERSION = "gevent/%s gunicorn/%s" % (gevent.__version__, gunicorn.__version__) VERSION = "gevent/%s gunicorn/%s" % (gevent.__version__, gunicorn.__version__)
def _gevent_sendfile(fdout, fdin, offset, nbytes): def _gevent_sendfile(fdout, fdin, offset, nbytes):
while True: while True:
try: try:
return os.sendfile(fdout, fdin, offset, nbytes) return os.sendfile(fdout, fdin, offset, nbytes)
except OSError as e: except OSError as e:
if e.args[0] == errno.EAGAIN: if e.args[0] == errno.EAGAIN:
wait_write(fdout) socket.wait_write(fdout)
else: else:
raise raise
@ -51,14 +50,7 @@ class GeventWorker(AsyncWorker):
wsgi_handler = None wsgi_handler = None
def patch(self): def patch(self):
from gevent import monkey monkey.patch_all()
monkey.noisy = False
# if the new version is used make sure to patch subprocess
if gevent.version_info[0] == 0:
monkey.patch_all()
else:
monkey.patch_all(subprocess=True)
# monkey patch sendfile to make it none blocking # monkey patch sendfile to make it none blocking
patch_sendfile() patch_sendfile()
@ -66,7 +58,7 @@ class GeventWorker(AsyncWorker):
# patch sockets # patch sockets
sockets = [] sockets = []
for s in self.sockets: for s in self.sockets:
sockets.append(socket(s.FAMILY, _socket.SOCK_STREAM, sockets.append(socket.socket(s.FAMILY, socket.SOCK_STREAM,
fileno=s.sock.fileno())) fileno=s.sock.fileno()))
self.sockets = sockets self.sockets = sockets
@ -165,34 +157,10 @@ class GeventWorker(AsyncWorker):
# by deferring to a new greenlet. See #1645 # by deferring to a new greenlet. See #1645
gevent.spawn(super(GeventWorker, self).handle_usr1, sig, frame) gevent.spawn(super(GeventWorker, self).handle_usr1, sig, frame)
if gevent.version_info[0] == 0: def init_process(self):
self.patch()
def init_process(self): hub.reinit()
# monkey patch here super(GeventWorker, self).init_process()
self.patch()
# reinit the hub
import gevent.core
gevent.core.reinit()
#gevent 0.13 and older doesn't reinitialize dns for us after forking
#here's the workaround
gevent.core.dns_shutdown(fail_requests=1)
gevent.core.dns_init()
super(GeventWorker, self).init_process()
else:
def init_process(self):
# monkey patch here
self.patch()
# reinit the hub
from gevent import hub
hub.reinit()
# then initialize the process
super(GeventWorker, self).init_process()
class GeventResponse(object): class GeventResponse(object):