I affectionately introduce YieldPoints, my littlest project yet. It's just some simple extensions to Tornado's gen module.
The cutest example of what you can do with YieldPoints is the WaitAny class, which lets you begin multiple asynchronous tasks and handle their results in the order they complete:
@gen.engine def f(): callback0 = yield gen.Callback(0) callback1 = yield gen.Callback(1) # Fire callback1 soon, callback0 later IOLoop.instance().add_timeout( timedelta(seconds=0.1), partial(callback1, 'foo')) IOLoop.instance().add_timeout( timedelta(seconds=0.2), partial(callback0, 'bar')) keys = set([0, 1]) while keys: key, result = yield yieldpoints.WaitAny(keys) print 'key:', key, ', result:', result keys.remove(key)
More examples are in the docs: you can use WithTimeout to wrap any callback in a timeout, and use Cancel or CancelAll to decline to wait for a callback you registered earlier. There's an adorable extended example that uses my library to start downloading multiple URLs at once, and process the results in the order received.