Пишите обратно через обратный вызов, прикрепленный к IOL oop в Tornado - PullRequest
0 голосов
/ 30 апреля 2020

Есть сложный обработчик записей, иногда это может занять много времени (в зависимости от входных значений), иногда нет.

Что я хочу, это писать обратно при каждой 1 секунде, динамически выделяя ответ.

def post():
    def callback():
        self.write('too-late')
        self.finish()

    timeout_obj = IOLoop.current().add_timeout(
        dt.timedelta(seconds=1),
        callback,
    )

    # some asynchronous operations

    if not self.request.connection.stream.closed():
        self.write('here is your response')
        self.finish()
        IOLoop.current().remove_timeout(timeout_obj)

Оказывается, я ничего не могу сделать изнутри callback.

Даже создание исключения подавляется внутренним контекстом и не будет пропущено через post метод.

Есть ли другие способы достижения цели?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 02 мая 2020

Пример использования tornado.gen.with_timeout. Имейте в виду, что задача должна быть асинхронной c, иначе IOL oop будет заблокирован и не сможет обработать тайм-аут:

@gen.coroutine
def async_task():
    # some async code

@gen.coroutine
def get(self):
    delta = datetime.timedelta(seconds=1)
    try:
        task = self.async_task()
        result = yield gen.with_timeout(delta, task)
        self.write("success")
    except gen.TimeoutError:
        self.write("timeout")
1 голос
/ 30 апреля 2020

Я бы посоветовал использовать https://github.com/aio-libs/async-timeout:

import asyncio
import async_timeout

def post():
    try:
        async with async_timeout.timeout(1):
            # some asynchronous operations

            if not self.request.connection.stream.closed():
                self.write('here is your response')
                self.finish()
                IOLoop.current().remove_timeout(timeout_obj)
    except asyncio.TimeoutError:
        self.write('too-late')
        self.finish()
...