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.