2017-05-18 79 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