diff options
author | Allan Saddi <allan@saddi.com> | 2009-10-21 09:29:33 -0700 |
---|---|---|
committer | Allan Saddi <allan@saddi.com> | 2009-10-21 09:29:33 -0700 |
commit | 3adf17edbd4a278ba7e02eaed4dc555d9729608b (patch) | |
tree | 1a55ffadbde159f0933107eb696d0987818795a6 /flup/server/scgi_base.py | |
parent | 90a38f2d6d156600bf73314986c5ff7d0960095d (diff) | |
download | flup-3adf17edbd4a278ba7e02eaed4dc555d9729608b.tar.gz |
Add configurable timeout (default: no timeout) to be used when the
WSGI application is called. Only applies to forked servers!
Diffstat (limited to 'flup/server/scgi_base.py')
-rw-r--r-- | flup/server/scgi_base.py | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/flup/server/scgi_base.py b/flup/server/scgi_base.py index e4f8f4c..091ddc1 100644 --- a/flup/server/scgi_base.py +++ b/flup/server/scgi_base.py @@ -37,6 +37,7 @@ import signal import datetime import os import warnings +import traceback # Threads are required. If you want a non-threaded (forking) version, look at # SWAP <http://www.idyll.org/~t/www-tools/wsgi/>. @@ -197,18 +198,28 @@ class Request(object): handlerTime.seconds + handlerTime.microseconds / 1000000.0) +class TimeoutException(Exception): + pass + class Connection(object): """ Represents a single client (web server) connection. A single request is handled, after which the socket is closed. """ - def __init__(self, sock, addr, server): + def __init__(self, sock, addr, server, timeout): self._sock = sock self._addr = addr self.server = server + self._timeout = timeout self.logger = logging.getLogger(LoggerName) + def timeout_handler(self, signum, frame): + self.logger.error('Timeout Exceeded') + self.logger.error("\n".join(traceback.format_stack(frame))) + + raise TimeoutException + def run(self): if len(self._addr) == 2: self.logger.debug('Connection starting up (%s:%d)', @@ -263,12 +274,22 @@ class Connection(object): # Allocate Request req = Request(self, environ, input, output) + # If there is a timeout + if self._timeout: + old_alarm = signal.signal(signal.SIGALRM, self.timeout_handler) + signal.alarm(self._timeout) + # Run it. req.run() output.close() input.close() + # Restore old handler if timeout was given + if self._timeout: + signal.signal(signal.SIGALRM, old_alarm) + + class BaseSCGIServer(object): # What Request class to use. requestClass = Request |