我使用龙卷风的ioloop有这个异步工作者功能。 我正试图在 Ctrl + C 上优雅地关闭循环但是出现以下错误
tornado.ioloop.TimeoutError:无秒后操作超时
我知道我能抓住它,但我确实希望以优雅的方式完成这个过程,我怎样才能实现呢?
#!/usr/bin/env python
import time
import signal
import random
from tornado import gen, ioloop, queues
concurrency = 10
def sig_exit(signum, frame):
ioloop.IOLoop.current().add_callback_from_signal(shutdown)
def shutdown():
print('Will shutdown in few seconds ...')
io_loop = ioloop.IOLoop.current()
deadline = time.time() + 3
def stop_loop():
now = time.time()
if now < deadline and (io_loop._callbacks or io_loop._timeouts):
io_loop.add_timeout(now + 1, stop_loop)
else:
io_loop.stop()
print('Shutdown')
stop_loop()
@gen.coroutine
def main():
q = queues.Queue()
q.put(1)
@gen.coroutine
def do_stuff():
print("doing stuff")
yield gen.Task(ioloop.IOLoop.instance().add_timeout, time.time() + random.randint(1, 5))
print("done doing stuff")
@gen.coroutine
def worker():
while True:
yield do_stuff()
for _ in range(concurrency):
worker()
yield q.join()
if __name__ == '__main__':
signal.signal(signal.SIGTERM, sig_exit)
signal.signal(signal.SIGINT, sig_exit)
io_loop = ioloop.IOLoop.instance()
io_loop.run_sync(main)
答案 0 :(得分:0)
如果您使用run_sync
,则无法再致电IOLoop.stop
- run_sync
现在负责此事。因此,如果您希望使此关闭“优雅”(而不是仅在您现在调用stop()
并使用堆栈跟踪退出时引发KeyboardInterrupt),则需要更改传递给{{1}的协同程序所以它退出了。
一种可能的解决方案是run_sync
:
tornado.locks.Event
答案 1 :(得分:0)
async def main():
tornado.options.parse_command_line()
...
app = Application(db)
app.listen(options.port)
shutdown_event = tornado.locks.Event()
def shutdown( signum, frame ):
print("shutdown database !!!!")
db.close()
shutdown_event.set()
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
await shutdown_event.wait()
print("\n\nshutdown -h now")
if __name__ == "__main__":
tornado.ioloop.IOLoop.current().run_sync(main)