2016-12-24 263 views
5

的正常關機,我用下面的代碼來關閉我的龍捲風應用優雅(從https://gist.github.com/wonderbeyond/d38cd85243befe863cdde54b84505784拍攝):龍捲風IOLoop

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列表E.g項目:

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

什麼是io_loop._timeouts的項目?我應該期望這是一個空的列表,還是我沒有阻止我應該擁有的東西?

這個關機程序是否正常?任何人都可以建議其他代碼

回答

2

停止龍捲風HTTPServer不會關閉所有現有連接,它只會阻止服務器接受新連接。有一個undocumented close_all_connections method,但它不區分空閒的連接和當前正在處理請求的連接,因此它不適合用於正常關閉。目前沒有任何方法可以在所有連接閒置時關閉連接。

每個空閒連接都會在IOLoop上保持超時(如果連接閒置時間過長,連接將會關閉,但默認爲一小時,將idle_connection_timeout=傳遞給HTTPServer構造函數以更改此設置)。此外,Tornado或其他庫的其他功能也可能會造成超時(在Tornado本身中,curl_httpclientautoreload都會創建超時,並始終運行),因此通常不能假定暫停超時的數量將達到零。

一般來說,我建議只是無條件地等待MAX_WAIT_SEC_BEFORE_SHUTDOWN,而不是試圖確定是否安全關閉更快。如果您確實想確定所有掛起操作何時完成,那麼最好自己保留掛起操作的計數(無論您認爲合適的「操作」的定義是什麼),而不是試圖從IOLoop的實現細節中推斷出這一點。

+0

謝謝本,一如既往非常翔實的答案。乾杯 –