Re: async networking (was Exploding feature set)

Andrew Bennetts <[email protected]>
Newsgroups gmane.comp.lang.prothon.user
Message-ID <20040712050132.GA31773@frobozz>
On Mon, Jul 12, 2004 at 11:53:48AM +1000, Robert Collins wrote:
> One twisted expert copied in.
> 
> Rob
> 
> On Mon, 2004-07-12 at 11:09, Mark Hahn wrote:
> > Paul Prescod wrote:
[...]
> > We are in agreement.  I didn't mean that async IO came for free with
> > stackless.  i just meant that a good async IO module should work well with
> > our stackless.  From what I understand if we implement a good foundation
> > then both async and sync will work on top of it.
> > 
[...]
> > > Prothon can't do everything but if you think you might want it to be a
> > > good platform for event-driven, asynch programming, it would be
> > > helpful to find some Twisted experts and ask them what they would
> > > like from a programming language by way of support.
> > 
> > Do you know any?  I can go to their website I guess and cold-email them.

Our mailing list at [email protected] would be a good place,
if you want to do that.  I expect you'll generate some interesting
discussion :)

In terms of core languages features that would help Twisted that Python
lacks, co-routines are the main thing that springs to my mind.

There is already a small module in Twisted's sandbox which is a
proof-of-concept for integrating Twisted with Stackless Python:
    http://svn.twistedmatrix.com/cvs/trunk/sandbox/radix/threadless.py?view=auto&rev=10441&root=Twisted

It would probably be worth asking Chris Armstrong, the author of that
proof-of-concept stackless for Twisted script, for his thoughts because he's
almost certainly spent more time thinking about all this than I have.  I've
CC'd him.

Co-routines would certainly help Twisted.  Currently, if you're in the
middle of e.g. processing a web request, and you need to postpone processing
for a while until an asynchronous event happens (e.g. the result of a
database query, or an XML-RPC call, or ...), it's a bit messy.  You need to
contrive a way to be able to return control to the event loop, but then be
able to resume what you were doing when the event happens -- but at that
point the call stack probably looks something like this:

    reactor (the event loop)
    socket logic (twisted.internet.tcp)
    HTTP logic (twisted.protocols.http)
    Web framework logic (twisted.web.server)
    Web templating logic (e.g. Nevow)
    Application/Business logic

(most recent call last, of course...)

That's a lot of layers to get through to get back to the reactor, and a lot
of layers to rebuild to go back again.  The first few layers aren't a big
issue: the reactor, the socket handler ("Protocol", in Twisted parlance),
and some of the HTTP handling are simple event handlers/dispatchers, and
once they've fired their event they can return immediately, and that's that.
But by the time enough dataReceived events have occured to cause a
requestReceived event, which starts the real application -- the web server,
the presentation layer, and the business logic -- the state of the
processing of that request is fairly complex, and fiddly to suspend and
resume.  Effectively, each layer needs to be able to cope with a message
from the next layer down saying "I'm not done yet, and I won't be done until
something else happens", and that needs to be passed all the way up the call
stack.

In short, the application code gets polluted to some extent with the nuts
and bolts of postponing the next step until later.

If Stackless Python were mainstream, I would expect that rather than trying
to unwind the call stack to get back to the reactor, the business of serving
each connection (and possibly even each request) would be a seperate
co-routine.  This would work essentially identically to now, except when
something wants to block until an event occurs.  Rather than needing to
unwind the entire call-stack with a series of "not quite done" placeholder
values, that co-routine would simply suspend itself and switch control
directly back to the event loop.  When the condition for the co-routine to
continue is met, it would switch back to that co-routine, and continue
processing that request from exactly where it left off.  This would reduce
the complexity of Twisted code significantly, I think.

One advantage of this approach is that code wouldn't need to be explicitly
written for Twisted to be useful in Twisted -- e.g. while you could use Zope
Page Templates in Twisted today, they'd be very limited, because they don't
know how to deal with results that aren't available yet, i.e. they don't
know about the "I'm not done yet" messages that other layers would pass to
them, meaning you could only use ZPT if you were comfortable with them
blocking your entire Twisted process.  With co-routines, I expect this
wouldn't be a problem.

In fact, Twisted has reimplemented several protocols from scratch that are
in the Python standard library, largely because the synchronous way the
standard library versions operate is completely useless to Twisted (the
ability to fix/add our own bugs is another factor <wink>).  It would be a
shame if the same thing happened all over again to Prothon, so that it had a
standard library of POP, HTTP, FTP and whatever else implemenations, and
then a Prothon user preferring an asynchronous model couldn't re-use that.

-Andrew.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.