[Twisted-Python] reset/restart reactor problem

Moof moof at metamoof.net
Sun Jun 25 05:39:16 MDT 2006


> >I am porting an academic middleware project, currently implemented in  C++
> >and Java, to python. It extensively uses multicast for  communicating
> >general events and TCP to communicate with a database.  The multicast
> >messages that I send out depend on the results that I  first obtain from the
> >database. I would prefer to serialise each of  these requests in turn, but
> >its not immediately obvious to me what  the best way to do this using
> >Twisted is.
>
> There are quite a few possible techniques to apply here.  One I would
> recommend is to keep a list of objects which represent pending tasks
> which need to be executed serially.  When each task completes, pop the
> next one from the list and begin processing it.  When a new task needs
> to be performed, push it onto the list.

[snip code]

This has already been implemented in twisted.

from twisted.internet import defer

requestqueue = defer.DeferredSemaphore(1) # only allow one token to be
in use at a time
d = requestqueue.run(object.method, arg1, arg2, arg3=3)

d is a deferred that will return the result of the method call in the
standard manner. The semaphore will store the function call in a FIFO
queue and run it when a token becomes available, acquiring the lock,
running, and releasing it once run. It allows for multiple tokens, so
it's normally used to run a maximum of, say, 30 things at a time, but
there's no reson not to set a maximum of 1. This guarantees that only
one call in the notional queue will be run at a time, effectively
serialising your requests.

Keep in mind that twisted is inherently single-threaded, and hence, to
an extent, serial in nature anyway, there are very few times in a
twisted programme when it becomes multi-threaded, database access with
twisted.enterprise being one of them. The general strategy would be to
keep only the part of your programme that needs to be transactional in
a queue like this, leaving the rest of the programme (like sending the
multicast data) in twisted's normal asynchronous execution space. In
fact, the only reason to do it this way is if you need to process the
data in the order it's received. If the order is not important, then
you can use your own database's transaction model to solve the
concurrency issues, (see
twisted.enterprise.adbapi.ConnectionPool.runInteraction), and just let
twisted gets on with doing things the way it knows best.

Hope this helps,

Moof




More information about the Twisted-Python mailing list