2017-05-18 80 views
2

假設我有一個簡單的Tornado Web服務器,開始是這樣的:如何分叉和執行服務器並等待它準備好?

app = ... # create an Application 
srv = tornado.httpserver.HTTPServer(app) 
srv.bind(port) 
srv.start() 
tornado.ioloop.IOLoop.instance().start() 

我寫的「終端到終端」的測試,這與subprocess.Popen,然後啓動服務器在一個單獨的進程通過HTTP調用服務器。現在我需要確保服務器沒有啓動失敗(例如,因爲端口繁忙),然後等待服務器準備就緒。

我寫了一個函數等到服務器已經準備好了:

def wait_till_ready(port, n=10, time_out=0.5): 
    for i in range(n): 
     try: 
      requests.get("http://localhost:" + str(port)) 
      return 
     except requests.exceptions.ConnectionError: 
      time.sleep(time_out) 

    raise Exception("failed to connect to the server") 

有沒有更好的辦法?

父進程如何分叉和執行服務器,確保服務器沒有因爲服務器端口忙而失敗? (如果需要,我可以更改服務器代碼)。

回答

1

您可以通過兩種方式來解決:

  1. 你之前做一個管道/隊列叉。然後,在開始io循環之前,通知父母一切正常,並且您已準備好接受請求。
  2. 打開端口並在分叉前綁定端口。你應該確保你關閉父母側的套接字。但除此之外,唯一需要在孩子身上運行的是io循環。您可以在分叉之前處理所有其他錯誤。
+0

感謝您的回答。它確實有幫助。我意識到我確實需要父母和子女過程之間的管道。當服務器退出時(例如,因爲它的監聽端口很忙而'bind'產生一個異常),管道的孩子的末端自動關閉(由OS)。現在我想知道父母如何知道管道是半封閉的,而無需等待管道同步。 – Michael