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> Xavier Grangier <grangier@gmail.com>
Sergey Shepelev <temotor@gmail.com> Sergey Shepelev <temotor@gmail.com>
Chris Dent <chris.dent@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 pass
except socket.error, e: except socket.error, e:
if e[0] not in (errno.EPIPE, errno.ECONNRESET): if e[0] not in (errno.EPIPE, errno.ECONNRESET):
self.log.exception("Error processing request.") self.log.exception("Socket error processing request.")
else: else:
if e[0] == errno.ECONNRESET: if e[0] == errno.ECONNRESET:
self.log.warn("Ignoring connection reset") self.log.warn("Ignoring connection reset")
@ -39,7 +39,7 @@ class AsyncWorker(Worker):
except UnexpectedEOF: except UnexpectedEOF:
self.log.exception("Client closed the connection unexpectedly.") self.log.exception("Client closed the connection unexpectedly.")
except Exception, e: except Exception, e:
self.log.exception("Error processing request.") self.log.exception("General error processing request.")
try: try:
# Last ditch attempt to notify the client of an error. # Last ditch attempt to notify the client of an error.
mesg = "HTTP/1.0 500 Internal Server Error\r\n\r\n" 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 conn, addr, gt = None, None, None
except eventlet.StopServe: except eventlet.StopServe:
return return
except:
self.log.exception("Unexpected error in acceptor. Sepuku.")
os._exit(4)
def cleanup(self, thread, conn): def cleanup(self, thread, conn):
try: try:

View File

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