龙卷风优雅地关闭IOLoop

时间:2016-12-24 05:29:13

标签: tornado

我正在使用以下代码优雅地关闭我的龙卷风应用程序(取自https://gist.github.com/wonderbeyond/d38cd85243befe863cdde54b84505784):

def sig_handler(servers, sig, frame):
    io_loop = tornado.ioloop.IOLoop.instance()

    def stop_loop(deadline):
        now = time.time()
        if now < deadline and (io_loop._callbacks or io_loop._timeouts):
            logging.info('Waiting for next tick')
            print("CALL BACKS")
            print(io_loop._callbacks)
            print("TIMEOUTS")
            print(io_loop._timeouts)
            io_loop.add_timeout(now + 1, stop_loop, deadline)
        else:
            io_loop.stop()
            logging.info("Shutting down.")

    def shutdown():
        logging.info("Stopping http servers")

        # servers is a list of servers to stop
        for s in servers:
           s.stop()

        logging.info("Will shutdown in %s seconds ...",
                     MAX_WAIT_SEC_BEFORE_SHUTDOWN)
        stop_loop(time.time() + MAX_WAIT_SEC_BEFORE_SHUTDOWN)

    logging.warning("Caught signal: %s", sig)
    io_loop.add_callback_from_signal(shutdown)

我将MAX_WAIT_SEC_BEFORE_SHUTDOWN设置为10秒。即使在关闭http服务器之后,每次都需要整整10秒来关闭服务器。我注意到io_loop._timeouts列表中总有一些项目:

[<tornado.ioloop._Timeout object at 0x106b90408>, <tornado.ioloop._Timeout object at 0x106b904c8>, ...]

io_loop._timeouts中有哪些项目?我应该期待这是一个空列表还是我不能阻止我应该拥有的东西?

此关闭程序是否正常?任何人都可以建议其他代码吗?

1 个答案:

答案 0 :(得分:3)

停止龙卷风HTTPServer不会关闭所有现有连接,它只会阻止服务器接受新连接。有一个undocumented close_all_connections method,但它不区分空闲的连接和当前正在处理请求的连接,因此它不适合在正常关闭时使用。目前没有任何方法可以在所有连接空闲时关闭它们。

每个空闲连接都会在IOLoop上保持超时(如果连接空闲时间过长,连接将被关闭,虽然默认值为1小时。将idle_connection_timeout=传递给HTTPServer构造函数改变这个)。此外,Tornado或其他库的其他功能也可能会产生超时(在Tornado本身,curl_httpclientautoreload都会创建始终运行的超时),因此您通常不能假设待处理的数量超时将永远达到零。

一般情况下,我建议只是无条件地等待MAX_WAIT_SEC_BEFORE_SHUTDOWN,而不是试图确定是否可以更快地关闭它。如果你确实想确定所有挂起操作何时完成,那么最好自己保留挂起操作的数量(对于&#34;操作&#34;你认为合适的)的任何定义,而不是试图从实现中推断出这一点IOLoop的详细信息。