[Twisted-Python] Deferreds and Tasklets
Simon Pickles
sipickles at hotmail.com
Sun Apr 6 10:42:02 MDT 2008
So I am still fiddling with interesting ways to combine stackless and
twisted. Its fun, but I am probably naively hacking! (I always seem to
want to use the deprecated code!- probably says a lot about me?)
I'm using Perspective Broker to do remote calls to an app running
Twisted-Stackless. PB is positively brilliant, btw.
So say the a remote caller wants to get data from my app. It calls
remote_GetData() in my PB app, which uses the actor model(each object
has a channel.receive() running in its own tasklet).
remote_GetData() has to send a message thru a stackless.channel() to get
the required data, then it must stackless.schedule()
Now it waits for the result to arrive at its own channel.receive(),
which then needs to be passed back as the return value of remote_GetData().
Is this possible?
Perhaps like this:
from twisted.spread import pb
from twisted.internet import reactor
import stackless
dbRx = stackless.channel()
pbRx = stackless.channel()
class DataSource:
def Listen(self):
while 1:
msg = dbrx.receive() # a channel will arrive here
msg.send(42)
stackless.schedule()
def __init__(self):
stackless.tasklet(self.Listen)()
class pbBroker(pb.Referenceable):
def remote_GetData(self):
dbRx.send(pbRx)
result = pbRx.receive()
# return 42 to remote caller thru pb
return result
This isn't ideal since I don't want pbBroker to block during the
receive. I'd like it to closer resemble the Listen loop of the first
class, so other objects can talk to pbBroker while it is waiting. Maybe
like this:
class pbBroker(pb.Referenceable):
def Listen(self):
while 1:
msg = self.rx.receive()
# do stuff with msg from other local objects
stackless.schedule()
def __init__(self):
self.rx = stackless.channel()
stackless.tasklet(self.Listen)()
def remote_GetData(self):
ch = stackless.channel()
dbRx.send(ch)
# can block since its a dedicated channel
result = ch.receive()
# return 42 to remote caller thru pb
return result
I guess the same problem arise when remote_GetData() has to use a
deferred too.
from twisted.enterprise import adbapi
dbPool = adbapi.ConnectionPool("MySQLdb", db="db", user="user",
passwd="pw")
class pbBroker(pb.Referenceable):
def remote_GetDeferredData(self):
d = dbPool.runInteraction(DoQuery, "SELECT * FROM users") #
DoQuery just wraps a query with try/except
d.addCallback(self.GetDeferredData_Success)
def GetDeferredData_Success(self, result):
# return to remote caller thru pb
return result ## WRONG
How can I return a value for a remote_* call when I only get that value
thru another callback?
Sorry its a long and confusing one!
Simon
--
Linux user #458601 - http://counter.li.org.
--
Linux user #458601 - http://counter.li.org.
More information about the Twisted-Python
mailing list