monkeypatch wsgi.sendfile for gevent

make sendfile usage non blocking with gevent
This commit is contained in:
benoitc 2013-08-27 18:18:35 +02:00
parent 4e3702c3ca
commit 25094605cf
2 changed files with 23 additions and 1 deletions

View File

@ -18,7 +18,7 @@ try:
from os import sendfile
except ImportError:
try:
from _sendfile import sendfile
from ._sendfile import sendfile
except ImportError:
sendfile = None

View File

@ -5,6 +5,7 @@
from __future__ import with_statement
import errno
import os
import sys
from datetime import datetime
@ -21,13 +22,31 @@ except ImportError:
raise RuntimeError("You need gevent installed to use this worker.")
from gevent.pool import Pool
from gevent.server import StreamServer
from gevent.socket import wait_write
from gevent import pywsgi
import gunicorn
from gunicorn.workers.async import AsyncWorker
from gunicorn.http.wsgi import sendfile as o_sendfile
VERSION = "gevent/%s gunicorn/%s" % (gevent.__version__, gunicorn.__version__)
def _gevent_sendfile(fdout, fdin, offset, nbytes):
while True:
try:
return o_sendfile(fdout, fdin, offset, nbytes)
except OSError as e:
if e.args[0] == errno.EAGAIN:
wait_write(fdout)
else:
raise
def patch_sendfile():
from gunicorn.http import wsgi
if o_sendfile is not None:
setattr(wsgi, "sendfile", _gevent_sendfile)
BASE_WSGI_ENV = {
'GATEWAY_INTERFACE': 'CGI/1.1',
'SERVER_SOFTWARE': VERSION,
@ -50,6 +69,9 @@ class GeventWorker(AsyncWorker):
monkey.noisy = False
monkey.patch_all()
# monkey patch sendfile to make it none blocking
patch_sendfile()
def notify(self):
super(GeventWorker, self).notify()
if self.ppid != os.getppid():