summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-12-24 02:27:55 -0500
committerChris McDonough <chrism@plope.com>2011-12-24 02:27:55 -0500
commitf30df644a6783172347f0597a99f4ced4286543b (patch)
treec257b48a50590e53151cd5d14a9d1fbe2ab4f9a2
parent03b91d10ee3fe82f671c09efc792c9c725333105 (diff)
downloadwaitress-f30df644a6783172347f0597a99f4ced4286543b.tar.gz
documentation gardening
-rw-r--r--TODO.txt5
-rw-r--r--waitress/adjustments.py42
-rw-r--r--waitress/channel.py8
-rw-r--r--waitress/server.py23
-rw-r--r--waitress/tests/test_regression.py12
5 files changed, 35 insertions, 55 deletions
diff --git a/TODO.txt b/TODO.txt
index 2404936..5a30b3d 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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