Question

I am writing this little demo code to start an HTTP server, test that it is running successfully and then exit.

import http.server
import urllib.request
import threading

# Start HTTP server
httpd = http.server.HTTPServer(('', 8080), http.server.SimpleHTTPRequestHandler)
thread = threading.Thread(target=httpd.serve_forever)
thread.start()

# Test HTTP server and shutdown
print(urllib.request.urlopen('http://127.0.0.1:8080/').read())
httpd.shutdown()

This seems to be working fine but it might be working fine due to luck. You see, I am invoking httpd.serve_forever in a separate thread, so that my script doesn't block at this call and it can continue with the urllib.request.urlopen call to test the HTTP server.

But I must ensure that I am making the urllib.request.urlopen call only after httpd.serve_forever has been invoked successfully and the server is now serving requests.

Is there any flag or any method in http.server.HTTPServer or socketserver.TCPServer that will help me to ensure that I begin testing it with urllib.request.urlopen only after it is ready to serve requests?

Was it helpful?

Solution

If your goal is to not get an empty / invalid answer in your urlopen, the answer is you won't. You actually open a socket with this line:

http.server.HTTPServer(...)

so after it (with still one thread running) you already have an open socket listening for incoming connections (although nothing dispatching requests yet). After that we may have a race of two threads. Consider both possibilities:

  1. The server thread runs serve_forever first. Well, it's the case you're aiming at.
  2. The main thread connects first. Your connection will be accepted and will wait for something to dispatch it to the handler. Then the server thread runs serve_forever, attaches a dispatcher and your request still gets processed.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top