diff options
-rw-r--r-- | docs/design.rst | 54 | ||||
-rw-r--r-- | docs/glossary.rst | 5 | ||||
-rw-r--r-- | docs/index.rst | 1 |
3 files changed, 60 insertions, 0 deletions
diff --git a/docs/design.rst b/docs/design.rst new file mode 100644 index 0000000..69731a7 --- /dev/null +++ b/docs/design.rst @@ -0,0 +1,54 @@ +Design +------ + +Waitress uses a combination of asynchronous and synchronous code to do its +job. It handles I/O to and from clients using the :term:`asyncore` library. + +The :term:`asyncore` module in the Python standard library: + +- Uses the ``select.select`` function to wait for connections from clients + and determine if a connected client is ready to receive output. + +- Creates a channel whenever a new connection is made to the server. + +- Executes methods of a channel whenever it believes data can be read from or + written to the channel. + +A "channel" is created for each connection from a client to the server. The +channel handles all requests over the same connection from that client. A +channel will handle some number of requests during its lifetime: zero to how +ever many HTTP requests are sent to the server by the client over a single +connection. For example, an HTTP/1.1 client may issue a theoretically +infinite number of requests over the same connection; each of these will be +handled by the same channel. An HTTP/1.0 client without a "Connection: +keep-alive" header will request usually only one over a single TCP +connection, however, and when the request has completed, the client +disconnects and reconnects (which will create another channel). When the +connection related to a channel is closed, the channel is destroyed and +garbage collected. + +When a channel determines the client has sent at least one full valid HTTP +request, it schedules a "task" with a "thread dispatcher". The thread +dispatcher maintains a fixed pool of worker threads available to do client +work (by default, 4 threads). If a worker thread is available when a task is +scheduled, the worker thread runs the task. The task has access to the +channel, and can write back to the channel's output buffer. When all worker +threads are in use, scheduled tasks will wait in a queue for a worker thread +to become available. + +I/O is always done asynchronously (by asyncore) in the main thread. Worker +threads never do any I/O. This means that 1) a large number of clients can +be connected to the server at once and 2) worker threads will never be hung +up trying to send data to a slow client. + +No attempt is made to kill a "hung thread". It's assumed that when a task +(application logic) starts that it will eventually complete. If for some +reason WSGI application logic never completes and spins forever, the worker +thread related to that WSGI application will be consumed "forever", and if +enough worker threads are consumed like this, the server will stop responding +entirely. + +Periodic maintenance is done by the main thread (the thread handling I/O). +If a channel hasn't sent or received any data in a while, the channel's +connection is closed, and the channel is destroyed. + diff --git a/docs/glossary.rst b/docs/glossary.rst index ac17a19..ad0876b 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -10,3 +10,8 @@ Glossary A system for configuration of WSGI web components in declarative ``.ini`` format. See http://pythonpaste.org/deploy/. + asyncore + A standard library module for asynchronous communications. See + http://docs.python.org/library/asyncore.html . + + diff --git a/docs/index.rst b/docs/index.rst index e421491..6882731 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -180,6 +180,7 @@ Extended Documentation .. toctree:: :maxdepth: 1 + design.rst differences.rst api.rst arguments.rst |