toro: Synchronization primitives for Tornado coroutines¶
Toro logo by Musho Rodney Alan Greenblat
With Tornado’s gen module, you can turn Python generators into full-featured coroutines, but coordination among these coroutines is difficult without mutexes, semaphores, and queues.
Toro provides to Tornado coroutines a set of locking primitives and queues analogous to those that Gevent provides to Greenlets, or that the standard library provides to threads.
Toro is completed and deprecated; its features have been merged into Tornado. Development of locks and queues for Tornado coroutines continues in Tornado itself.
The Wait / Notify Pattern¶
>>> import toro >>> from tornado import ioloop, gen >>> loop = ioloop.IOLoop.current() >>> condition = toro.Condition() >>> @gen.coroutine ... def waiter(): ... print "I'll wait right here" ... yield condition.wait() # Yield a Future ... print "I'm done waiting" ... >>> @gen.coroutine ... def notifier(): ... print "About to notify" ... condition.notify() ... print "Done notifying" ... >>> @gen.coroutine ... def runner(): ... # Yield two Futures; wait for waiter() and notifier() to finish ... yield [waiter(), notifier()] ... loop.stop() ... >>> future = runner(); loop.start() I'll wait right here About to notify Done notifying I'm done waiting
Wait-methods take an optional
deadline argument, which is either an
loop = ioloop.IOLoop.current() # Wait up to 1 second for a notification yield condition.wait(deadline=loop.time() + 1)
datetime.timedelta for a deadline relative to the current time:
# Wait up to 1 second yield condition.wait(deadline=datetime.timedelta(seconds=1))
If there’s no notification before the deadline, the Toro-specific
Timeout exception is raised.
The Get / Put Pattern¶
Queue.get()waits until there is an available item in the queue, and may notify a coroutine waiting to put an item.
Queue.put()waits until the queue has a free slot, and may notify a coroutine waiting to get an item.
See the Producer-consumer example.
- Frequently Asked Questions