James Saiz : Using Python Coroutines for AJAX Applications

James Saiz

journeyman of some

Using Python Coroutines for AJAX Applications

I think I just had an epiphany regarding the upcoming coroutine support in Python. I don't mean I came up with anything new (I think Ruby programmers have been doing it for a long time), just that I finally grok it—or at least, I think I do.

You see, I'm writing a little AJAX-based flash card website and I started off writing a standalone dynamic HTML mock-up of (obviously) the client side but without any communication to the server yet.

I then wrote a console-based flash card program to experiment with the algorithm I want to use for what card to show when, when to learn new cards, etc. The console-based program just has a function called test that takes a card object, tests the card on the user and returns a boolean as to whether the user got the card right or not.

So my code has a bunch of places where I say:

for card in to_test:
    correct = test(card)
    if correct:
        ...
    else:
        ...

In theory, it's only this test function that's throw away. It would be nice if I just had to replace those calls to test when I come to write the server version.

The only catch is that it will be the client that initiates requests for cards. Easy, I thought: I can use yield statements in the server code wherever I want to present the user with the next card. That way, the client (or more accurately some proxy for the client running on the server) can do a next() to get the next card.

The problem is that the client needs to return the result. The yield can't be a one-way street. At the point the server yields a card, it needs to also find out the result of that yield.

Enter coroutines. If I understand correctly, this is exactly the kind of problem coroutines solve. The yield statement in my server-side code becomes a yield expression. The client sends the generator the result of testing the card and that becomes what the yield expression evaluates to.

Have I understood coroutines correctly? If so, I can't wait for Python 2.5!

Categories: Python

Trackbacks (0)

Comments (8)

Tim on Sunday 13 November, 2005:

That's an interesting project you are working on. :-)

James Saiz on Sunday 13 November, 2005:

Wanna help? :-)

Fredrik on Sunday 13 November, 2005:

You don't need any new mechanisms to implement this, of course: just use a shared variable (e.g. an instance variable) to get data from the framework back into the generator. An example:

http://effbot.org/zone/asyncore-generators.htm

Michael on Sunday 13 November, 2005:

A generalised framework for "talking" to active generators can be found here:
http://kamaelia.sf.net/

The tutorial (miniaxon/how it works) shows the basic underlying principles of the system should you want to use Kamaelia or that sort of approach.

We've not really done anything in the web area with Kamaelia or it's core concurrency framework (Axon), but there's no real reason you couldn't use it to do what you want. I'd be very interested in helping if you're interested in trying Kamaelia (or more accurately Axon) or just the general ideas.

Unlike PEP342 generators, your communication point isn't forced to be synchronous to yield points, decoupling the ends of the transaction.

James Saiz on Monday 14 November, 2005:

Thanks for the links.

Note that I want the yield points to be synchronous. The "dealer" doesn't need to do anything until the "player" requests a card.

The appeal of the PEP342 approach is that I'd only need to change one thing in my code: correct = test(card) becomes correct = yield card

Ashok on Monday 14 November, 2005:

Great project!

I've been "scratching an itch"...My daughter is learning addition/subtraction and uses a flash card site. My biggest problem - traffic slows down response - and she's complaining of having to wait too long... we're trying to build up her speed - and the network is slowing her down...

Not sure if what you're suggesting will fix that....

A

James Saiz on Tuesday 15 November, 2005:

Ashok,

Using XmlHttpRequest to request new cards should be much quicker than having to load a whole new page for each new card. It could be even faster if I load a bunch of cards at a time and just send the responses back asynchronously.

Jon on Saturday 25 February, 2006:

Do you have an alpha up for the flash card site? Would like to see how it works.

Add a Comment

What is 64+3?
Name
URI
Comment
Comments are text only.
The math question is to ensure you are a human!
This page last modified Sunday 13 November, 2005
Content made available under a Creative Commons Attribution-NonCommercial-ShareAlike license