Моя установка - сервер торнадо python, который асинхронно обрабатывает задачи с помощью ThreadPoolExecutor
. В некоторых условиях задача может превратиться в бесконечный цикл. С помощью декоратора with_timeout
мне удалось поймать исключение тайм-аута и вернуть клиенту результат ошибки. Проблема в том, что задача все еще работает в фоновом режиме. Как можно остановить выполнение задачи в ThreadPoolExecutor
? Или можно отменить Future
? Вот код, который воспроизводит проблему. Выполните код с торнадо 4 и concurrent.futures библиотеками и перейти к http://localhost:8888/testКак я могу отменить зависающую асинхронную задачу в торнадо с тайм-аутом?
from tornado.concurrent import run_on_executor
from tornado.gen import with_timeout
from tornado.ioloop import IOLoop
import tornado.web
from tornado import gen
from concurrent.futures import ThreadPoolExecutor
import datetime
MAX_WAIT_SECONDS = 10
class MainHandler(tornado.web.RequestHandler):
executor = ThreadPoolExecutor(2)
@run_on_executor
def test_func(self):
...
#infinite loop might be here
...
@tornado.gen.coroutine
def get(self):
future = self.test_func()
try:
result_search_struct = yield with_timeout(datetime.timedelta(seconds=MAX_WAIT_SECONDS), future)
self.write({'status' : 0})
self.finish()
except Exception, e:
#how to cancel the task here if it was timeout
future.cancel() # <-- Does not work
self.write({'status' : 100})
self.finish()
application = tornado.web.Application([
(r"/test", MainHandler),
])
application.listen(8888)
IOLoop.instance().start()
Даны, спасибо за ответ, проблема заключается в том, что нет никакой реальной «петли». Существует тонкая ошибка, которая все еще находится под следствием, которая вызывает бесконечную петлю внутри задачи. В качестве временного решения я отменил отмену нити. Я не уверен, как это сделать в текущей структуре кода. –
Я изменил свой код, поэтому он не будет путать, что существует реальный цикл –
@EgorLakomkin См. [Этот вопрос] (http://stackoverflow.com/questions/323972/is-there-any-way-to-kill- a-thread-in-python) об уничтожении потока в Python. Есть некоторые вещи, которые вы можете сделать, которые будут работать в некоторых обстоятельствах, но на самом деле нет единого подхода, который будет работать для всех случаев использования. Большинство подходов там особенно проблематичны, потому что вы используете «ThreadPoolExecutor», а не объект «Thread» напрямую. – dano