[Python-Dev] Synchronous and Asynchronous servers in the standard library

"Martin v. Löwis" martin at v.loewis.de
Wed Nov 10 08:36:22 CET 2004


Jp Calderone wrote:

> See http://www.kegel.com/dkftpbench/Poller_bench.html#setup.solaris
> for some specific numbers, as well as a link to a simple benchmark
> tool you can try out (if you have a BSD machine).  None of these
> speak to Python overhead, but even assuming a huge number, like 30ms
> per event notification (which we choose to apply only to KQueue and
> not poll, because we're giving poll the benefit of the doubt), KQueue
> is already a win at 100 sockets.  Most important here is that KQueue
> (and related mechanisms - IOCP on Windows, and AIO on Linux (if it
> supported sockets ;)) scale with the number of active sockets, rather
> than the total number of sockets, as the other schemes do.  A KQueue
> server with 1000 quiescent clients and 1 active client is paying the
> same cost as a KQueue server with 1 active client; a poll server is
> paying between 500x and 1000x as much.

Again, my question is: so what? If I have 1000 idle clients, and one
active client, it appears that poll will need 1ms per call (1184 µs
on a 650 MHz dual Pentium). This is followed by the actual processing,
which will take *much* longer (depending on the nature of processing,
of course). A http server, for example, would need to parse the request,
locate the file, and start sending it back. This might take 10ms and
more.

Perhaps people really build Python servers which have simultaneously
30000 sockets open; I don't know.

> Say we have an SMTP/TCP server class, SMTP_TCP.  It inherits a
> buffering, error handling, etc, write() method from some helpful base
> class.  This version of write() handles socket.errors and deals with
> short send()s and so forth.  How can we write SMTP_TLS?  If it is a
> subclass of SMTP_TCP, then it inherits all the wrong socket behavior,
> because eventually it will need to deal with SSL send()s and recv()s.

I fail to see the problem. If the file object is replaced/rewrapped
into a SSL object, the base class can continue to use
read/write/send/recv - if only the SSL object supported the same
operations (which it really should if switching from plain sockets
to SSL sockets is a common task) (and you seem to be suggesting that
as a good strategy).

My point here is that you just cannot use the very same class for
SMTP, and SMTP+STARTTLS - you indicated that a subclass must be
created. This was my original point: you cannot instantiate the
baseclass for use with TLS, as the baseclass does not implement
the cmd_STARTTLS method.

> These can all be handled with relative ease.  Since I was so long
> winded above, I'll try and keep this short:
> 
> def cmd_STARTTLS(self): 
 >     if self.transport.canStartSSL():
>         self.transport.write('220 Begin TLS negotiation now\r\n') 
>         self.transport = SSLConnection(self.transport) 
 >     else:
>         self.transport.write('454 TLS not available\r\n')
> 
> The exact spelling of "self.transport.canStartSSL()" can go in any of
> a number of ways, but that is a different discussion. ;)

This cannot work, atleast not for the problem I was discussing:
In https, there is no starttls command to be implemented in a
subclass. Instead, the TLS negotiation occurs at connection
establishment, or transparently at any point during the
conversation.

The base class knows nothing about certificates, and client
authentification. So again, we need another class that deals
with these aspects of the protocol. Those aspects are *tied*
to the transport - so the resulting class will be
transport-specific.

> Another way to put all of this is that by separating the protocol
> from the transport, the library is required to provide P + T classes,
> where P is the number of supported protocols and T is the number of
> supported transports.  By statically defining all permutations of the
> two, the library is required to provide P * T classes.  Aside from
> the extra effort required, many users won't be interested in anything
> near the full permutation space in any single application, and so
> will be just as happy to create the pairs themselves, as necessary.

Who has required the library to provide P*T classes? That was a very
foolish design decision, as the users only need a small selection of
combinations. As a library designer, I would have created those
pairs that my users actually need.

Regards,
Martin



More information about the Python-Dev mailing list