diff options
author | Chris McDonough <chrism@plope.com> | 2011-12-24 02:27:55 -0500 |
---|---|---|
committer | Chris McDonough <chrism@plope.com> | 2011-12-24 02:27:55 -0500 |
commit | f30df644a6783172347f0597a99f4ced4286543b (patch) | |
tree | c257b48a50590e53151cd5d14a9d1fbe2ab4f9a2 | |
parent | 03b91d10ee3fe82f671c09efc792c9c725333105 (diff) | |
download | waitress-f30df644a6783172347f0597a99f4ced4286543b.tar.gz |
documentation gardening
-rw-r--r-- | TODO.txt | 5 | ||||
-rw-r--r-- | waitress/adjustments.py | 42 | ||||
-rw-r--r-- | waitress/channel.py | 8 | ||||
-rw-r--r-- | waitress/server.py | 23 | ||||
-rw-r--r-- | waitress/tests/test_regression.py | 12 |
5 files changed, 35 insertions, 55 deletions
@@ -48,4 +48,7 @@ - Waitress Version number in header. -- Timeout tests. +- Put maintenance check on server rather than channel. + +- Ensure upload streams can not exceed a maximum size. + diff --git a/waitress/adjustments.py b/waitress/adjustments.py index 163d4e9..52ec3a0 100644 --- a/waitress/adjustments.py +++ b/waitress/adjustments.py @@ -22,6 +22,7 @@ class Adjustments(object): all sockets, or you can create a new instance of this class, change its attributes, and pass it to the channel constructors. """ + # wsgi url scheme url_scheme = 'http' # backlog is the argument to pass to socket.listen(). @@ -30,26 +31,21 @@ class Adjustments(object): # recv_bytes is the argument to pass to socket.recv(). recv_bytes = 8192 - # send_bytes is the number of bytes to send to socket.send(). - # Multiples of 9000 should avoid partly-filled packets, but don't - # set this larger than the TCP write buffer size. In Linux, - # /proc/sys/net/ipv4/tcp_wmem controls the minimum, default, and - # maximum sizes of TCP write buffers. + # send_bytes is the number of bytes to send to socket.send(). Multiples + # of 9000 should avoid partly-filled packets, but don't set this larger + # than the TCP write buffer size. In Linux, /proc/sys/net/ipv4/tcp_wmem + # controls the minimum, default, and maximum sizes of TCP write buffers. send_bytes = 9000 - # copy_bytes is the number of bytes to copy from one file to another. - copy_bytes = 65536 + # A tempfile should be created if the pending output is larger than + # outbuf_overflow, which is measured in bytes. The default is 1MB. This + # is conservative. + outbuf_overflow = 1048576 - # Create a tempfile if the pending output data gets larger - # than outbuf_overflow. With RAM so cheap, this probably - # ought to be set to the 16-32 MB range (circa 2001) for - # good performance with big transfers. The default is - # conservative. - outbuf_overflow = 1050000 - - # Create a tempfile if the data received gets larger - # than inbuf_overflow. - inbuf_overflow = 525000 + # A tempfile should be created if the pending input is larger than + # inbuf_overflow, which is measured in bytes. The default is 512K. This + # is conservative. + inbuf_overflow = 524288 # Stop accepting new connections if too many are already active. connection_limit = 100 @@ -58,18 +54,16 @@ class Adjustments(object): cleanup_interval = 300 # Maximum seconds to leave an inactive connection open. - channel_timeout = 900 + channel_timeout = 60 # Boolean: turn off to not log premature client disconnects. - log_socket_errors = 1 + log_socket_errors = True - # The socket options to set on receiving a connection. - # It is a list of (level, optname, value) tuples. - # TCP_NODELAY is probably good for Zope, since Zope buffers - # data itself. + # The socket options to set on receiving a connection. It is a list of + # (level, optname, value) tuples. TCP_NODELAY is probably good for Zope, + # since Zope buffers data itself. socket_options = [ (socket.SOL_TCP, socket.TCP_NODELAY, 1), ] - default_adj = Adjustments() diff --git a/waitress/channel.py b/waitress/channel.py index c2883f1..84dcb4b 100644 --- a/waitress/channel.py +++ b/waitress/channel.py @@ -96,6 +96,7 @@ class HTTPServerChannel(asyncore.dispatcher, object): self.last_activity = time.time() def readable(self): + self.check_maintenance(time.time()) if not self.async_mode: return False return not self.will_close @@ -152,6 +153,13 @@ class HTTPServerChannel(asyncore.dispatcher, object): Closes connections that have not had any activity in a while. The timeout is configured through adj.channel_timeout (seconds). + + CM: the maintenance method never closes the channel upon which it is + called, it closes any other channel that is a) not running a task and + b) has exceeded its inactivity timeout. Since channel maintenance is + only done at channel creation time, this means that an inactive + channel will not be closed until at least one other channel is + created. """ now = time.time() cutoff = now - self.adj.channel_timeout diff --git a/waitress/server.py b/waitress/server.py index 78fba85..c517a8f 100644 --- a/waitress/server.py +++ b/waitress/server.py @@ -23,20 +23,12 @@ from waitress.compat import reraise class WSGIHTTPServer(asyncore.dispatcher, object): """ - if __name__ == '__main__': - import asyncore from waitress.taskthreads import ThreadedTaskDispatcher td = ThreadedTaskDispatcher() td.setThreadCount(4) server = WSGIHTTPServer('', 8080, task_dispatcher=td) server.run() - - try: - asyncore.loop() - except KeyboardInterrupt: - print 'shutting down...' - td.shutdown() """ channel_class = HTTPServerChannel @@ -191,21 +183,6 @@ class WSGIHTTPServer(asyncore.dispatcher, object): if hasattr(app_iter, 'close'): app_iter.close() - - - - ## def executeRequest(self, task): - ## headers = task.request_data.headers - ## if 'CONTENT_LENGTH' in headers: - ## cl = headers['CONTENT_LENGTH'] - ## task.response_headers['Content-Length'] = cl - ## instream = task.request_data.getBodyStream() - ## while 1: - ## data = instream.read(8192) - ## if not data: - ## break - ## task.write(data) - def run(self): try: asyncore.loop() diff --git a/waitress/tests/test_regression.py b/waitress/tests/test_regression.py index d822812..bde01b2 100644 --- a/waitress/tests/test_regression.py +++ b/waitress/tests/test_regression.py @@ -11,11 +11,9 @@ # FOR A PARTICULAR PURPOSE. # ############################################################################## -"""Tests for waitress.serverchannelbase zombie logic +"""Tests for waitress.channel maintenance logic """ import doctest -import unittest - class FakeSocket: # pragma: no cover data = '' @@ -43,10 +41,10 @@ def zombies_test(): """Regression test for HTTPServerChannel.maintenance method Bug: This method checks for channels that have been "inactive" for a - configured time. The bug was that last_activity is set at creation time but - never updated during async channel activity (reads and writes), so any - channel older than the configured timeout will be closed when a new channel - is created, regardless of activity. + configured time. The bug was that last_activity is set at creation time + but never updated during async channel activity (reads and writes), so + any channel older than the configured timeout will be closed when a new + channel is created, regardless of activity. >>> import time >>> import waitress.adjustments |