Async callback in python

L

Linan

Hi,

In javascript, code could be written like this:

....

var _p=XMLHttpRequest();
_p.open('GET',url,true);
_p.send(null);
_p.onreadystateChange=function(){
if(_p.readyState==4)
cb(_p.responseText);
}
....

This basic AJAX code allows function to be called when it's invoked,
without blocking the main process. There is same library asyncore in
python. However, I can't validate it's asynchronous through code:
class T(asyncore.dispatcher):
def __init__(self,host,url):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host,80))
self.url='GET %s HTTP/1.0\r\n\r\n' % url

def handle_connect(self):
pass

def handle_close(self):
self.close()

def handle_read(self):
print 'READING.....'
print self.recv(256)

def handle_write(self):
sent=self.send(self.url)
self.url=self.url[sent:]

t=T('aVerySlowSite','/')
asyncore.loop()
for i in range(0,10):
print '%d in main process' % i
time.sleep(1)

Suppose it's asynchronous, couple of '%d in main process' lines should
be mixed in the output of T.handle_read(), right? But I found that
actually main process was blocked at asyncore.loop(), until the the
socket was closed. My questions:
1, Did I do anything wrong?
2, Is it real asynchronous?
3, If not, where to get the real one(s)?

Any comment is welcome :)
 
T

tleeuwenburg

Did you flush the buffer?

It might be that the print statements are being called in the order you
expect but that they are all written to the screen only at the end.
I've had that happen before.

Cheers,
-T
 
C

Calvin Spealman

Hi,

In javascript, code could be written like this:

...

var _p=XMLHttpRequest();
_p.open('GET',url,true);
_p.send(null);
_p.onreadystateChange=function(){
if(_p.readyState==4)
cb(_p.responseText);
}
...

This basic AJAX code allows function to be called when it's invoked,
without blocking the main process. There is same library asyncore in
python. However, I can't validate it's asynchronous through code:
class T(asyncore.dispatcher):
def __init__(self,host,url):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host,80))
self.url='GET %s HTTP/1.0\r\n\r\n' % url

def handle_connect(self):
pass

def handle_close(self):
self.close()

def handle_read(self):
print 'READING.....'
print self.recv(256)

def handle_write(self):
sent=self.send(self.url)
self.url=self.url[sent:]

t=T('aVerySlowSite','/')
asyncore.loop()
for i in range(0,10):
print '%d in main process' % i
time.sleep(1)

Suppose it's asynchronous, couple of '%d in main process' lines should
be mixed in the output of T.handle_read(), right? But I found that
actually main process was blocked at asyncore.loop(), until the the
socket was closed. My questions:
1, Did I do anything wrong?
2, Is it real asynchronous?
3, If not, where to get the real one(s)?

Any comment is welcome :)

You seem to be confusing the terms "asyncronous" and "threaded".
Although multi-threading is a way to implement asyncronous software,
it is not the only or the best way to get those results. Usually the
term "asyncronous" is attached to non-threaded methods, because
"multi-threading" is usually just used for those threaded methods.

Thus, solutions like asyncore are ways to allow asyncronous code
without threading, and usually this involves a loop, as with asyncore,
and until all the asyncronous operations running in the loop are
complete, the loop does not end.

If you wanted to have these prints interlaced in the http download,
you might schedule them as a seperate asyncronous operation.

I hope that helped.

PS - Another, more complete asyncronous framework is the Twisted
project (http://www.twistedmatrix.com/)
 
G

Gabriel Genellina

t=T('aVerySlowSite','/')
asyncore.loop()
for i in range(0,10):
print '%d in main process' % i
time.sleep(1)

Suppose it's asynchronous, couple of '%d in main process' lines should
be mixed in the output of T.handle_read(), right?

No. As you noticed, asyncore.loop (without arguments) won't return
until all channels are closed.
But I found that
actually main process was blocked at asyncore.loop(), until the the
socket was closed.
Exactly.

My questions:
1, Did I do anything wrong?
2, Is it real asynchronous?
3, If not, where to get the real one(s)?

Perhaps you didn't understand the nature of asyncore processing. The
idea is not to have many threads, each one blocking on its own
(synchronous) socket processing. Instead, using a single thread which
never blocks, and dispatches events to many instances, each one
processing its own data.
If you want to do other things mixed with network events, put those
things inside the loop, that is, instead of asyncore.loop() do something like:

while asyncore.socket_map:
asyncore.loop(1, count=1)
// do other things


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
C

Chris Mellon

Hi,

In javascript, code could be written like this:

...

var _p=XMLHttpRequest();
_p.open('GET',url,true);
_p.send(null);
_p.onreadystateChange=function(){
if(_p.readyState==4)
cb(_p.responseText);
}
...

This basic AJAX code allows function to be called when it's invoked,
without blocking the main process. There is same library asyncore in
python. However, I can't validate it's asynchronous through code:
class T(asyncore.dispatcher):
def __init__(self,host,url):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host,80))
self.url='GET %s HTTP/1.0\r\n\r\n' % url

def handle_connect(self):
pass

def handle_close(self):
self.close()

def handle_read(self):
print 'READING.....'
print self.recv(256)

def handle_write(self):
sent=self.send(self.url)
self.url=self.url[sent:]

t=T('aVerySlowSite','/')
asyncore.loop()
for i in range(0,10):
print '%d in main process' % i
time.sleep(1)

Suppose it's asynchronous, couple of '%d in main process' lines should
be mixed in the output of T.handle_read(), right? But I found that
actually main process was blocked at asyncore.loop(), until the the
socket was closed. My questions:
1, Did I do anything wrong?
2, Is it real asynchronous?
3, If not, where to get the real one(s)?

Any comment is welcome :)

You seem to be confusing the terms "asyncronous" and "threaded".
Although multi-threading is a way to implement asyncronous software,
it is not the only or the best way to get those results. Usually the
term "asyncronous" is attached to non-threaded methods, because
"multi-threading" is usually just used for those threaded methods.

Thus, solutions like asyncore are ways to allow asyncronous code
without threading, and usually this involves a loop, as with asyncore,
and until all the asyncronous operations running in the loop are
complete, the loop does not end.

If you wanted to have these prints interlaced in the http download,
you might schedule them as a seperate asyncronous operation.

I hope that helped.

PS - Another, more complete asyncronous framework is the Twisted
project (http://www.twistedmatrix.com/)

In addition to the above, you misinterpret the way the posted
JavaScript works. JavaScript uses a "run to completion" model and, in
browsers, is purely event-based. There is no "main process" to block,
and if you simulate one via a loop, the code you posted won't work.

Except in IE, because it violates the ecmascript standard and will
'call back' from the implementation to the javascript environment
without regard for the current state of that environment.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top