--- TODO 2001/10/31 09:46:06 1.28
+++ TODO 2001/10/31 13:11:25 1.29
@@ -2,18 +2,6 @@
TODO
----
-Oh, finally, a performance issue (that probably doesn't matter for
-lmtp2nntp):
-sa_rc_t sa_read(sa_t *sa, char *cpBuf, size_t nBufReq, size_t *nBufRes)
-always flushes the write portion of the outgoing stream, even if the
-read is going to be entirely from the local buffer. This is generally
-undesirably behavior, since you can trigger nagle's algorithm if
-you're a command/response server with pipelining like LMTP.
-Generally, you want to flush the write portion whenever you're about
-to block on a read, but not necessarily before.
-(Of course, the client-side of a pipelining client is considerably
-more complex.)
-
- on resolving multiple addresses can be returned (especially
one IPv4 and one IPv6!) and each one has to be tried on
socket+connect for instance. What to do? See also
@@ -26,6 +14,24 @@
CANDO
-----
+o Nagle's Algorithm and Flushing of Output Buffers.
+
+ The kernel performs Nagle's Algorithm (see RFC 896 and search for "nagle
+ algorithm" on www.whatis.com [currently
+ http://searchnetworking.techtarget.com/sDefinition/0,,sid7_gci754347,00.html]
+ on his internal output buffers. Although we flush our user-space output
+ buffers only if we really perform a read(2) (and not if the read is going to
+ be served entirely from the local buffer) this does not mean that really
+ every character the remote has already sent is also already read by us.
+ Because the kernel also has a read buffer. Optimal behaviour would be that
+ we flush out output buffer only if the read(2) would block. OTOH flushing
+ out buffers means performing a write(2) and this again is buffered in the
+ kernel, too. So performing an optimal read->write->read->write->... sequence
+ is very complex and non-trivial to implement. Especially because even using
+ Nagle's Algorithm always is not the right choice (see
+ http://www.w3.org/Protocols/HTTP/Performance/Nagle/ for details), especially
+ when it comes to pipelining protocols.
+
o Support for writev(2).
This can be done by internally switching to always use writev(2),
|