Reputation: 22252
I'm trying to implement a variant of this question using tornado Futures. The queues a problem, because I don't want to past data being accumulated. IOW, I want the one http request handler to block waiting for result of another that occurs AFTER the original has started.
But I think I'm missing a step.
My code looks like:
Events = dict()
class EventHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def get(self, unit):
# create future to block on
future = tornado.concurrent.Future()
# store the future at a place the produce can find it
Events[unit] = future
# block waiting for the future's response
result = yield future.result()
# deregister the future
Events.pop(unit, None)
self.write(result)
@tornado.gen.coroutine
def post(self, unit):
# fetch the corresponding future if there is one
future = Events.get(unit, None)
if future:
# found one, set the result to pass body over
future.set_result(self.request.body)
else:
print('noop')
self.write(bytes())
What happens is that I get errors that look like:
File "./foo.py", line 44, in get
result = yield future.result()
File "/usr/lib/python3/dist-packages/tornado/concurrent.py", line 216, in result
self._check_done()
File "/usr/lib/python3/dist-packages/tornado/concurrent.py", line 294, in _check_done
raise Exception("DummyFuture does not support blocking for results")
Am I not using the Future correctly? Is there an additional step I need to do in configuring it? Am I supposed to make a subclass that implements that _check_done
behavior? Is my assumption that a tornado Future
was synonymous with other systems calla a promise
incorrect? Is there some different way to do this than just using a future/promise?
Upvotes: 1
Views: 1280
Reputation: 94901
You need to use
result = yield future
Not
result = yield future.result()
yield future.result()
is actually equivalent to yield <whatever is returned by future.result()>
. If the result isn't ready yet, that means that the result()
API would have to block (meaning, block the tornado event loop) until the result is ready, and tornado.concurrent.Future
doesn't support that. You can only wait for the result using the non-blocking yield future
construct.
Upvotes: 2