-->

How to fork and exec a server and wait until it

2019-07-17 17:47发布

问题:

Suppose I've got a simple Tornado web server, which starts like this:

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

I am writing an "end-to-end" test, which starts the server in a separate process with subprocess.Popen and then calls the server over HTTP. Now I need to make sure the server did not fail to start (e.g. because the port is busy) and then wait till server is ready.

I wrote a function to wait until the server gets ready :

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") 

Is there a better way ?

How can the parent process, which forks and execs the server, make sure that the server didn't fail because the server port is busy for example ? (I can change the server code if I need it).

回答1:

You could approach it in two ways:

  1. Make a pipe / queue before you fork. Then, just before you start the io loop, notify the parent that everything went fine and you're ready for the request.
  2. Open the port and bind to it before forking. You should make sure you close that socket on the parent side. But otherwise, the only thing which needs to run in the child is the io loop. You can handle all the other errors before the fork.