/usr/share/doc/python-medusa-doc/html/data_flow.html is in python-medusa-doc 1:0.5.4-7.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | <h1>Data Flow in Medusa</h1>
<img src="data_flow.gif">
<p>Data flow, both input and output, is asynchronous. This is
signified by the <i>request</i> and <i>reply</i> queues in the above
diagram. This means that both requests and replies can get 'backed
up', and are still handled correctly. For instance, HTTP/1.1 supports
the concept of <i>pipelined requests</i>, where a series of requests
are sent immediately to a server, and the replies are sent as they are
processed. With a <i>synchronous</i> request, the client would have
to wait for a reply to each request before sending the next.</p>
<p>The input data is partitioned into requests by looking for a
<i>terminator</i>. A terminator is simply a protocol-specific
delimiter - often simply CRLF (carriage-return line-feed), though it
can be longer (for example, MIME multi-part boundaries can be
specified as terminators). The protocol handler is notified whenever
a complete request has been received.</p>
<p>The protocol handler then generates a reply, which is enqueued for
output back to the client. Sometimes, instead of queuing the actual
data, an object that will generate this data is used, called a
<i>producer</i>.</p>
<img src="producers.gif">
<p>The use of <code>producers</code> gives the programmer
extraordinary control over how output is generated and inserted into
the output queue. Though they are simple objects (requiring only a
single method, <i>more()</i>, to be defined), they can be
<i>composed</i> - simple producers can be wrapped around each other to
create arbitrarily complex behaviors. [now would be a good time to
browse through some of the producer classes in
<code>producers.py</code>.]</p>
<p>The HTTP/1.1 producers make an excellent example. HTTP allows
replies to be encoded in various ways - for example a reply consisting
of dynamically-generated output might use the 'chunked' transfer
encoding to send data that is compressed on-the-fly.</p>
<img src="composing_producers.gif">
<p>In the diagram, green producers actually generate output, and grey
ones transform it in some manner. This producer might generate output
looking like this:
<pre>
HTTP/1.1 200 OK
Content-Encoding: gzip
Transfer-Encoding: chunked
Header ==> Date: Mon, 04 Aug 1997 21:31:44 GMT
Content-Type: text/html
Server: Medusa/3.0
Chunking ==> 0x200
Compression ==> <512 bytes of compressed html>
0x200
<512 bytes of compressed html>
...
0
</pre>
<p>Still more can be done with this output stream: For the purpose of
efficiency, it makes sense to send output in large, fixed-size chunks:
This transformation can be applied by wrapping a 'globbing' producer
around the whole thing.</p>
<p>An important feature of Medusa's producers is that they are
actually rather small objects that do not expand into actual output
data until the moment they are needed: The <code>async_chat</code>
class will only call on a producer for output when the outgoing socket
has indicated that it is ready for data. Thus Medusa is extremely
efficient when faced with network delays, 'hiccups', and low bandwidth
clients.
<p>One final note: The mechanisms described above are completely
general - although the examples given demonstrate application to the
<code>http</code> protocol, Medusa's asynchronous core has been
applied to many different protocols, including <code>smtp</code>,
<code>pop3</code>, <code>ftp</code>, and even <code>dns</code>.
|