it's better to test when you use the right code to do it. We had a

blocking operation django example (we read a file already on the fs and
recreate another which blocked async schedulers).

While I'm here ease the code of eventlet worker. Just use the convenient
eventlet.serve function which already manage what we do and revert sopme
useless changes in body and header parsing.
This commit is contained in:
benoitc 2010-09-02 14:55:56 +02:00
parent 7e4ca4b809
commit 7715199b48
7 changed files with 39 additions and 65 deletions

View File

@ -66,6 +66,11 @@ MIDDLEWARE_CLASSES = (
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
FILE_UPLOAD_HANDLERS = (
"django.core.files.uploadhandler.TemporaryFileUploadHandler",
)
ROOT_URLCONF = 'djangotest.urls'
TEMPLATE_DIRS = (

View File

@ -18,6 +18,7 @@ def home(request):
subject = None
message = None
size = 0
print request.META
if request.POST:
form = MsgForm(request.POST, request.FILES)
print request.FILES
@ -25,11 +26,7 @@ def home(request):
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
f = request.FILES['f']
tmp = tempfile.TemporaryFile()
for chunk in f.chunks():
tmp.write(chunk)
tmp.flush()
size = int(os.fstat(tmp.fileno())[6])
size = int(os.fstat(f.fileno())[6])
else:
form = MsgForm()

View File

@ -450,7 +450,7 @@ class Arbiter(object):
os.unlink(worker.tmpname)
except:
pass
def spawn_workers(self):
"""\
Spawn new workers as needed.

View File

@ -223,12 +223,11 @@ class Body(object):
idx = self.buf.getvalue().find("\n")
while idx < 0:
pos = self.buf.tell() - 1
data = self.reader.read(1024)
if not len(data):
break
self.buf.write(data)
idx = self.buf.getvalue()[pos:].find("\n")
idx = self.buf.getvalue().find("\n")
if size < self.buf.tell():
break

View File

@ -137,25 +137,21 @@ class Request(Message):
# Headers
pos = 0
idx = buf.getvalue().find("\r\n\r\n")
done = buf.getvalue()[:2] == "\r\n"
while idx < 0 and not done:
pos = buf.tell() - 4
self.get_data(unreader, buf)
idx = buf.getvalue()[pos:].find("\r\n\r\n")
idx = buf.getvalue().find("\r\n\r\n")
done = buf.getvalue()[:2] == "\r\n"
if done:
self.unreader.unread(buf.getvalue()[2:])
return ""
end = pos + idx
self.headers = self.parse_headers(buf.getvalue()[:end])
self.headers = self.parse_headers(buf.getvalue()[:idx])
ret = buf.getvalue()[end+4:]
ret = buf.getvalue()[idx+4:]
buf.truncate(0)
return ret

View File

@ -5,15 +5,13 @@
from __future__ import with_statement
import errno
import socket
import os
import eventlet
from eventlet.green import os
from eventlet import hubs
from eventlet.greenio import GreenSocket
from gunicorn.workers.async import AsyncWorker
class EventletWorker(AsyncWorker):
@ -24,55 +22,29 @@ class EventletWorker(AsyncWorker):
if eventlet.version_info < (0,9,7):
raise RuntimeError("You need eventlet >= 0.9.7")
eventlet.monkey_patch(os=False)
def init_process(self):
hubs.use_hub()
super(EventletWorker, self).init_process()
def timeout_ctx(self):
return eventlet.Timeout(self.cfg.keepalive, False)
def acceptor(self, pool):
try:
while self.alive:
try:
client, addr = self.socket.accept()
pool.spawn_n(self.handle, client, addr)
except socket.error, e:
if e[0] not in (errno.EAGAIN, errno.ECONNABORTED):
raise
if pool.running() > self.worker_connections:
continue
try:
hubs.trampoline(self.socket.fileno(), read=True,
timeout=self.timeout)
except eventlet.Timeout:
pass
except eventlet.StopServe:
pool.waitall()
return eventlet.Timeout(self.cfg.keepalive, False)
def run(self):
self.socket = GreenSocket(family_or_realsock=self.socket.sock)
self.socket.setblocking(1)
self.acceptor = eventlet.spawn(eventlet.serve, self.socket,
self.handle, self.worker_connections)
pool = eventlet.GreenPool(self.worker_connections)
acceptor = eventlet.spawn(self.acceptor, pool)
try:
while self.alive:
self.notify()
if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s" % self)
server.stop()
break
eventlet.sleep(0.1)
except KeyboardInterrupt:
pass
while self.alive:
self.notify()
if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s" % self)
break
eventlet.sleep(0.1)
self.notify()
with eventlet.Timeout(self.timeout, False):
eventlet.kill(acceptor, eventlet.StopServe)
self.log.info("are we blocking?")
eventlet.kill(self.acceptor, eventlet.StopServe)
self.log.info("no sir!")

View File

@ -77,15 +77,17 @@ class GeventWorker(AsyncWorker):
if self.ppid != os.getppid():
self.log.info("Parent changed, shutting down: %s" % self)
break
gevent.sleep(0.1)
gevent.sleep(0.1)
except KeyboardInterrupt:
pass
try:
# Try to stop connections until timeout
self.notify()
server.stop(timeout=self.timeout)
except:
pass
def handle_request(self, *args):
try:
super(GeventWorker, self).handle_request(*args)
@ -137,11 +139,14 @@ class GeventBaseWorker(Worker):
break
gevent.sleep(0.1)
except KeyboardInterrupt:
pass
# try to stop the connections
try:
self.notify()
server.stop(timeout=self.timeout)
except gevent.GreenletExit:
pass
except KeyboardInterrupt:
except:
pass