#python-3.x #tornado
Вопрос:
Каков был бы наилучший подход для установки условия тайм-аута для задачи/функции, которая была отправлена в ThreadPoolExecutor с помощью декоратора @run_on_executor tornado.concurrent? Пример обработчика торнадо ниже:
import json
import time
import tornado.web
from concurrent.futures import ThreadPoolExecutor
from tornado.concurrent import run_on_executor
class MyHandler(tornado.web.RequestHandler):
def initialize(self) -> None:
self.executor = ThreadPoolExecutor(1)
@run_on_executor
def blocking_function(self) -> None:
""" Run Blocking Function on ThreadPoolExecutor. """
seconds = 10
time.sleep(seconds)
response = json.dumps({"message": f"Slept for {seconds} seconds."})
return response
async def get(self) -> None:
response = await self.blocking_function()
self.write(response)
Существует ли что-то подобное tornado.gen.with_timeout
найденному здесь для @run_on_executor?
Спасибо, что уделили мне время.
Ответ №1:
Поскольку run_on_executor
возвращает Future
объект, вы можете использовать его с gen.with_timetout
:
from datetime import timedelta
async def get(self):
response = await gen.with_timeout(
timedelta(seconds=5),
self.blocking_function()
)
...
Не забудьте обработать исключение тайм-аута.
Комментарии:
1. Эй, @xyres, спасибо за ваш ответ, но эти опции, похоже, обеспечивают поведение «вызов через 5 секунд», когда на самом деле я прошу «отменить через 5 секунд». Поэтому в моем примере я бы хотел
async def get(self)
, чтобы вызов вызывал исключение, если соблюдено значение тайм-аута (например, 5 секунд). В данном случае так и должно быть, потомуblocking_function()
что для завершения вызова должно потребоваться более или равно 10 секунд. Я могу отредактировать исходный вопрос, если вы считаете, что это было непонятно, еще раз спасибо.2. Извините, я раньше не понял вопроса. Теперь я обновил свой ответ. Посмотрим, поможет ли это.
3. Именно то, что было нужно, спасибо!