일부 쉘 명령을 실행하는 웹 서버가 있습니다. 이 명령은 보통 2 초가 걸리지 만 어떤 경우에는 더 많은 시간이 걸리고 클라이언트 (웹 브라우저 나 컬이 아닙니다)의 연결이 끊어집니다.토네이도 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를'yield with_timeout (datetime.timedelta (seconds = TIMEOUT), 서브 프로세스 (args = ('sleep % d'% duration) .split()). wait_for_exit())' – Graf