[Twisted-Python] Converting async to sync code (blocking until deferreds fire)
Jack Whitham
jack-tp at cs.york.ac.uk
Tue Jul 22 10:22:33 EDT 2008
> >What is the best way to convert asynchronous code (non-blocking,
> >returning deferreds) to synchronous code (blocking)?
Ok, I've considered all three of the suggested solutions, and
I think Phil Mayer's suggestion of "yield" suits my requirements
best. In the hope of helping others with a similar problem I
will summarise the suggestions.
1. t.i.threads.blockingCallFromThread
This method blocks until a callback/errback is called,
but it *doesn't* run the reactor's event loop, so you
need at least two threads: one to block, and another to run
the reactor. Therefore it can only be used to convert async to
sync code in a multithreaded environment. My programs are single
threaded so this doesn't work. And as Barry Wark points out,
threads are not a "favored solution" :).
2. Trial _wait
twisted.trial.unittest has a _wait method which is used by some
tests to wait for deferreds to fire. However, the only clean
way to use this _wait method is to write a test case! If this
were C++ or Java, this method would be "private" - it's only
externally accessible because Python doesn't have "private".
3. yield
Since my program is not multithreaded and not a test case,
the use of yield is most suitable. Here is how yield is used
in this context:
http://twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks
This does have some restrictions, not least that Python 2.5 is
needed. When you use "yield" in a method, it becomes a
generator, with different semantics to a conventional method.
Nevertheless, your code *looks* like a sequential program.
I'd like to thank everyone who made a suggestion, this has
been very helpful!
--
Jack Whitham
jack at cs.york.ac.uk
More information about the Twisted-Python
mailing list