2016-09-02 3 views
1

Я пытаюсь реализовать вариант this question с использованием торнадо Futures. Очереди проблемы, потому что я не хочу, чтобы прошлые данные накапливались. IOW, я хочу, чтобы один обработчик запроса HTTP блокировал ожидание результата другого, которое происходит после того, как оригинал был запущен.confused by tornado.concurrent.Future exception

Но я думаю, что мне не хватает шага.

Мой код выглядит следующим образом:

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()) 

Что происходит, что я получаю ошибки, которые выглядят как:

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") 

ли я не использовать будущее правильно? Есть ли еще один шаг, который мне нужно сделать для его настройки? Я должен сделать подкласс, который реализует это поведение _check_done? Является ли мое предположение, что торнадо Future был синонимом других систем: calla a promise? Есть ли другой способ сделать это, чем просто использовать будущее/обещание?

ответ

2

Вы должны использовать

result = yield future 

Не

result = yield future.result() 

yield future.result() фактически эквивалентно yield <whatever is returned by future.result()>. Если результат еще не готов, это означает, что API result() должен блокировать (что означает, блокировать цикл событий торнадо), пока результат не будет готов, а tornado.concurrent.Future не поддерживает это. Вы можете только ждать результата, используя неблокирующую конструкцию yield future.

 Смежные вопросы

  • Нет связанных вопросов^_^