mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
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:
parent
7e4ca4b809
commit
7715199b48
@ -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 = (
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
@ -450,7 +450,7 @@ class Arbiter(object):
|
||||
os.unlink(worker.tmpname)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def spawn_workers(self):
|
||||
"""\
|
||||
Spawn new workers as needed.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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!")
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user