У меня есть веб-сервер, который запускает некоторую команду оболочки. Обычно команда занимает пару секунд, но в некоторых случаях требуется больше, и в этом случае клиент (это не веб-браузер или завиток) отключается.Tornado with_timeout правильное использование
У меня нет возможности исправить клиента, поэтому я подумал об исправлении сервера. Он основан на системе торнадо. Я переписал его с помощью функции tornado.gen.with_timeout, но по какой-то причине он не работает, как я ожидаю. Я устанавливаю тайм-аут до 5 секунд, поэтому при запросе сервера я ожидаю получить либо «законченный за X секунд» (где X < 5), либо «уже занял более 5 секунд ... все еще работает». И в обоих случаях я ожидаю получить ответ менее чем за 5 секунд.
Вот код:
import os
import json
import datetime
import random
from tornado.ioloop import IOLoop
from tornado.web import RequestHandler, Application
from tornado.gen import coroutine, with_timeout, TimeoutError, Return
@coroutine
def run_slow_command(command):
res = os.system(command)
raise Return(res)
class MainHandler(RequestHandler):
@coroutine
def get(self):
TIMEOUT = 5
duration = random.randint(1, 15)
try:
yield with_timeout(datetime.timedelta(seconds=TIMEOUT), run_slow_command('sleep %d' % duration))
response = {'status' : 'finished in %d seconds' % duration}
except TimeoutError:
response = {'status' : 'already took more than %d seconds... still running' % TIMEOUT}
self.set_header("Content-type", "application/json")
self.write(json.dumps(response) + '\n')
def make_app():
return Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8080)
IOLoop.current().start()
А вот выход из завитка:
for i in `seq 1 5`; do curl http://127.0.0.1:8080/; done
{"status": "finished in 15 seconds"}
{"status": "finished in 12 seconds"}
{"status": "finished in 3 seconds"}
{"status": "finished in 11 seconds"}
{"status": "finished in 13 seconds"}
Что я делаю неправильно?
Это сработало! Я полностью удалил командную строку 'run_slow_command' (в конце концов, это была только оболочка вокруг' os.system'), а в предложении try ... except я заменил свой исходный доход на 'yield with_timeout (datetime.timedelta (seconds = TIMEOUT), Subprocess (args = ('sleep% d'% duration) .split()). Wait_for_exit()) ' – Graf