summaryrefslogtreecommitdiff
path: root/flup/server/scgi_base.py
diff options
context:
space:
mode:
authorAllan Saddi <allan@saddi.com>2009-10-21 09:29:33 -0700
committerAllan Saddi <allan@saddi.com>2009-10-21 09:29:33 -0700
commit3adf17edbd4a278ba7e02eaed4dc555d9729608b (patch)
tree1a55ffadbde159f0933107eb696d0987818795a6 /flup/server/scgi_base.py
parent90a38f2d6d156600bf73314986c5ff7d0960095d (diff)
downloadflup-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.py23
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