Tornado @gen.coroutine закрывает длинное соединение для опроса

Привет, у меня проблема с инфраструктурой Tornado, реализующей долгий опрос. Метод post моего обработчика запросов украшен как @asynchronous, так и @gen.coroutine. Когда я оставляю его зависшим для вызова обратного вызова для обратной записи клиенту, соединение немедленно закрывается. Я видел, что это связано с использованием @gen.coroutine, который автоматически вызывает self.finish(), когда все фьючерсы получены. Мне нужен этот декоратор, потому что я использую Mongo Motor. Краткий пример ниже:

@web.asynchronous
@gen.coroutine
def post(self):
  #mongo Motor yielding code  
  notifications.register_callback(self.on_message)

Уведомления — это глобальный объект, который хранит массив обратных вызовов и вызывает их при получении сообщения извне. Спасибо


person Peterdeka    schedule 17.10.2014    source источник


Ответы (1)


Вам нужно использовать @gen.engine вместо @gen.coroutine, если вы хотите использовать yield для вызова сопрограмм, но не вызывать self.finish() автоматически в конце обработчика. В коде декоратора @web.asynchronous есть комментарий, который отмечает это:

# If @asynchronous is used with @gen.coroutine, (but
# not @gen.engine), we can automatically finish the
# request when the future resolves.  Additionally,
# the Future will swallow any exceptions so we need
# to throw them back out to the stack context to finish
# the request.

Таким образом, если @asynchronous используется с @gen.coroutine, он автоматически вызовет self.finish, но пропустит его, если используется с @gen.engine.

person dano    schedule 17.10.2014
comment
@Peterdeka Да, вы должны иметь возможность использовать тот же синтаксис для вызова motor. - person dano; 17.10.2014