Avoid a deadlock when the acceptor loop raises.

An out of file descriptors error was causing the async acceptor loops to
die. The notification process was unaffected so the workers didn't die.

Async workers hitting an error in the acceptor now kill themselves and
rely on the arbiter to restart a new worker in their stead.
This commit is contained in:
Paul J. Davis 2010-05-11 23:33:48 -04:00
parent db5bd53c4e
commit 0a46d09c6e
5 changed files with 15 additions and 2 deletions

1
THANKS
View File

@ -10,3 +10,4 @@ Johan Bergström <bugs@bergstroem.nu>
Xavier Grangier <grangier@gmail.com>
Sergey Shepelev <temotor@gmail.com>
Chris Dent <chris.dent@gmail.com>
Matt Good <matt@matt-good.net>

6
examples/bad.py Normal file
View File

@ -0,0 +1,6 @@
import tempfile
files = []
def app(environ, start_response):
files.append(tempfile.mkstemp())
start_response('200 OK', [('Content-type', 'text/plain'), ('Content-length', '2')])
return ['ok']

View File

@ -30,7 +30,7 @@ class AsyncWorker(Worker):
pass
except socket.error, e:
if e[0] not in (errno.EPIPE, errno.ECONNRESET):
self.log.exception("Error processing request.")
self.log.exception("Socket error processing request.")
else:
if e[0] == errno.ECONNRESET:
self.log.warn("Ignoring connection reset")
@ -39,7 +39,7 @@ class AsyncWorker(Worker):
except UnexpectedEOF:
self.log.exception("Client closed the connection unexpectedly.")
except Exception, e:
self.log.exception("Error processing request.")
self.log.exception("General error processing request.")
try:
# Last ditch attempt to notify the client of an error.
mesg = "HTTP/1.0 500 Internal Server Error\r\n\r\n"

View File

@ -62,6 +62,9 @@ class EventletWorker(AsyncWorker):
conn, addr, gt = None, None, None
except eventlet.StopServe:
return
except:
self.log.exception("Unexpected error in acceptor. Sepuku.")
os._exit(4)
def cleanup(self, thread, conn):
try:

View File

@ -60,6 +60,9 @@ class GEventWorker(AsyncWorker):
conn, addr, gt = None, None, None
except greenlet.GreenletExit:
return
except:
self.log.exception("Unexpected error in acceptor. Sepuku.")
os._exit(4)
def cleanup(self, gt):
try: