Christopher Stawarz ha scritto:
On May 6, 2008, at 6:17 AM, Manlio Perillo wrote:

I'm glad to know that there are some other people interested in asynchronous application, do you have seen my extensions to WSGI in my module for Nginx?

Yes, I have, and I had your module in mind as a potential provider of the AWSGI interface.

Note that in Nginx the request body is pre-read before the application is called (in fact wsgi.input is either a cStringIO or File object).

Although I didn't state it explicitly in my spec, my intention is for the server to be able to implement awsgi.input in any way it likes, as long as it provides a recv() method. It's totally acceptable for the request body to be pre-read.


Ok.
But what I meant was that since Nginx pre-read the request body I have not tried to implement an interface for dealing with an asynchronous wsgi.input ;-).


Moreover I don't see any readons to have a revc method instead of read.

Unfortunately there is a *big* usability problem: the extension is based on a well specified feature of WSGI: the gateway can suspend the execution of the WSGI application when it yields.

However if the asynchronous code is present in a "child" function, we have something like this:
...
That is, all the functions in the "chain" have to yield, and is not very good.

Yes, you're right. However, if you're willing/able to use Python 2.5, you can use the new features of generators to implement a call stack that lets you call child functions and receive return values and exceptions from them. I've implemented this in awsgiref.callstack. Have a look at

http://pseudogreen.org/bzr/awsgiref/examples/echo_request_with_callstack.py

for an example of how it works.


I don't think this will solve the problem.
Moreover in your example you buffer the whole request body so that you have to yield only one time.

The solution is to use coroutines, and I'm planning to integrate greenlets (from the pylib project) into the WSGI module for Nginx.

Interesting, but it's not clear to me how/if this would work. Can you explain more or point me to some code?


http://codespeak.net/py/dist/greenlet.html

def process_commands(*args):
    while True:
        line = ''
        while not line.endswith('\n'):
            line += read_next_char()
        if line == 'quit\n':
            print "are you sure?"
            if read_next_char() != 'y':
                continue    # ignore the command
        process_command(line)


With greenlets the execution can be suspened by any of the functions called by the main greelet.

This has a lot of advantages.

You can implement wsgi.input.read(n) so that it will suspend the execution of the current greenlet until *all* the n bytes have been read.

You can also implement the write callable so that control is returned to the main greelet when the socket is ready to send more data.

And, of course, you can implement a poll like interface and a sleep like interface.


I think that it is a great advantage, moreover it is the only way to implement truly reusable components.

Note that there is an effort of integrating greenlets with Twisted:
http://radix.twistedmatrix.com/2008/03/corotwine-01.html


The "problem" is that once you add support to greenlets, you have no more WSGI.

The interface can be the same, and applications can work on it without problems, but the semantic is *completely* different.


Also note that with greenlets should be possible to "magically" transform blocking applications like Django to non blocking.



The main problem I see with greenlet is that is is not yet stable (there are some problems with the garbage collector) and that is is not part of CPython.

This means that it can be not acceptable to write a PEP for a WSGI like interface with coroutine support.



Thanks,
Chris



Regards  Manlio Perillo
_______________________________________________
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com

Reply via email to