[Twisted-Python] Twisted sure is Twisted :)

Andrew Bennetts andrew-twisted at puzzling.org
Sat Aug 30 19:53:35 MDT 2003


On Sat, Aug 30, 2003 at 04:34:58AM -0600, John Janecek wrote:
> Twisted once u get a grip on it sure is pretty impressive.
> I used twisted to forward UDP packets as a relay. Take one
> UDP packet and then retrans it to many other clients. On
> a FreeBSD box P3 750 the delay in retrans on packet to
> like 5 clients was less then 1ms which was very impressive.
> 
> In using twisted i know the reactor is broken in wxpython.
> 
> What would happen if u ran a normal reactor in a seperate thread,
> and then passed the info from twisted into wxpython using an event
> handler similar to the wxpython thread demo ??

You could use reactor.callInThread(myWxMainLoop), I guess -- but last time I
looked at wxpython, it *had* to be run in the main thread, so this might get
slightly messy (I'm pretty sure the Twisted reactor doesn't mind being run
in a non-main thread, so this shouldn't be insurmountable).  Of course, it's
been quite a while since I've used wxpython, so this might not be an issue
anymore.

> The only problem with that is i can not see how u would pass info
> from wxpython back into twisted. Hmmmm maybe if u made a queue,

Just use reactor.callFromThread -- a thread can call this to safely schedule a
function to be run in the main event loop.  See
http://twistedmatrix.com/documents/howto/threading.  

> The idea behind deferred is intresting. The defered call back does not
> seem to fire until it is added. How the heck does that work ? I am
> refering to the database example. Hmmmm not really important but kinda
> neat.

Deferred callbacks obviously can't fire until they're added to the deferred,
but of course they might not fire immediately upon addCallback, though --
because the deferred might not have been called yet.

> def getAge(user):
>     return dbpool.runQuery("SELECT age FROM users WHERE name = ?", user)
> 
> def printResult(l):
>     if l:
>         print l[0][0], "years old"
>     else:
>         print "No such user"
> 
> d=getAge("joe")
> d.addCallback(printResult)
> 
> like here d is the function getAge. My gut instict tell me the moment I

No, here 'd' is a deferred result from the function 'getAge'.  A deferred is
simply an object that represents a result that probably hasn't arrived yet.

> call getAge the database query should be run. But yet it is not run till u
> add the callback.  and if i add an errorback after it, it is not run till
> it has been added also, I can not see how it works :)). Hmmmm must be part
> of the magic :))

So, in this case, dbpool.runQuery ducks off and runs the database query in a
thread behind the scenes, and returns immediately without waiting for the
result to arrive -- because databases can take an arbitrarily long time to
return a result.  In the meantime, the code that called runQuery can add
callbacks and errbacks to the deferred result from runQuery, and the
deferred will see to it that those are run when the result does arrive (if
the result has already arrived by the time you add a callback, it will be
run immediately).

The running of the callback is completely independent to the running of the
query.  If you never add any callbacks or errbacks and just discard the
deferred from dbpool.runQuery immediately, the query is still run on the
database -- it's just that when the twisted.enterprise.adbapi code gets the
result back from the database, it will fire the deferred (using
Deferred.callback or Deferred.errback), and the deferred will find it has no
callbacks to trigger, which is fine.

If you haven't already, read http://twistedmatrix.com/documents/howto/defer.

[...]
> Anyway this is the crap i ramble off at 4 am :)
> Just basically wanted to say twisted is cool.

Thanks!  :)

-Andrew.





More information about the Twisted-Python mailing list