Has anyone created a simple POP3 and SMTP server using TWISTED?

Jp Calderone exarkun at intarweb.us
Tue Mar 18 03:39:03 CET 2003

On Tue, Mar 18, 2003 at 12:55:29AM +0000, Donn Cave wrote:
> Quoth Jp Calderone <exarkun at intarweb.us>:
> | On Mon, Mar 17, 2003 at 10:45:44PM +0000, Donn Cave wrote:
> |> Quoth "Steve Holden" <sholden at holdenweb.com>:
> |> | "Donn Cave" <donn at drizzle.com> wrote in message
> |> | news:1047616632.623178 at yasure...
> |> ...
> |> |> But there are some limitations.  One that comes to mind is that an
> |> |> open socket doesn't survive across a fork, so you may want to start
> |> |
> |> | If this is so, how does inetd work?
> |> 
> |> Doesn't.
> |> 
> |
> |   You're kidding, right?
> Not at all.  Why?

  Because inetd does work.  This is easily demonstrable.  I invite you to
connect to my ident port, for example.

  Perhaps you meant that inetd performs poorly under some circumstances? 
Or is undesirable for some other reason?

> |>|> with a single-threaded server that deals with each connection one
> |>|> by one.  That should work for POP and SMTP, though probably will need
> |>|> a select with timeout in front of all reads, so the occasional stuck
> |>|> client doesn't jam the works.
> |>|
> |>| I'm not sure I can agree with this. Are you suggesting that it isn't
> |>| possible to concurrently handle multiple connections to the same server
> |>| port, or am I misunderstanding?
> |> 
> |> That is indeed possible - it's Berkeley sockets to that extent.  The 
> |> problem is only that without fork, you need to use threads, and that
> |> adds some implementation problems that it seems to me you might
> |> profitably postpone until at least the 2nd generation.  Unless multi-
> |> threaded programs are second nature to you already, but then in that
> |> case you'd probably disregard my advice anyway.  (Using "you" in the
> |> impersonal sense.)
> |   This is wrong.  http://python.org/doc/lib/socket-objects.html - See the
> | setblocking() method.
> |
> |   I can only assume that such selective ignorance of reality is feigned, and
> | you simply have a personal dislike of asynchronous and non-blocking network
> | architectures.
> Yes and no - I don't much care for setblocking(), if that's what you
> mean by a non-blocking network architecture, but I actually am a big
> fan of asynchronous operations.  But if you're going to handle multiple
> concurrent clients with select() and/or non-blocking sockets, that still
> leaves you with a good deal of work to do, work that other implementors
> of these services never had to do because each connection runs in its
> own fork.  Given the choice between that and threads, I would say threads
> in this case (as they are well supported by the platform.)  But (again,
> in this case, for the details of which I am going to have to hope you
> have actually been following the present thread) either is unnecessarily
> complex given the requirements.

  Indeed, merely using non-blocking sockets is a little feeble, I'd much
rather use kqueue or even AIO - maybe someday soon these will be available
both on a platform that is in widespread use and to software written in

  select() is still better than threads, though (I feel no need to qualify
this - we all know that very few things are *always* true).

  One could take the time to re-implement all the required support code for
an asynchronous application, or one could simply use tools already
available.  Or will you argue that no such tools exist? :)

  Threading ties you to an arbitrarily low number of clients - many popular
operating systems can't even scale past a thousand running threads.  Though
some platforms seem to be moving beyond this limitation, they're not quite
there yet.  Threading also introduces such problems as deadlocks, race
conditions, and resource starvation, problems which can be avoided, to be
sure, but only at a significant cost in developer time.

  You might argue that these can be avoided by proper use of thread-local
data and properly protected access to what very limited shared data is
allowed to exist, but one might also argue that this design is equally
suited to a fork()'ing application that uses IPC, or better still, one which
runs multiple processes independantly (maybe on different machines) and
communicates via sockets.

  Or is this wrong, too?


 up 14 days, 17:59, 4 users, load average: 0.06, 0.06, 0.02

More information about the Python-list mailing list