Search code examples
pythonmultithreadingsimplehttpserver

How to reliably know that HTTPServer in a separate thread is up and serving?


I'm starting a HTTPServer object in a new thread:

from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading

with HTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
    thread = threading.Thread(target=httpd.serve_forever, daemon=True)
    thread.start()
    # Doing my work ...
    httpd.shutdown()

Here, I would like to ensure that httpd.serve_forever() has successfully started before # doing my work... is reached. I can certainly insert thread.join(timeout=1) after thread.start(), but this still risks race condition. Is there a reliable way to wait until serve_forever is up and running?


Solution

  • Sure thing. There's a callback called service_actions which is called after every iteration of the serve_forever loop, and you can use a threading.Event() in there you can wait on.

    Since the callback is called after each possibly serviced request, it will cause an initial delay of up to 0.5 seconds (by default), but I don't think that's a problem. If it is, you can override serve_forever to do it before the first request service.

    import threading
    from http.server import HTTPServer, SimpleHTTPRequestHandler
    
    
    class SignalingHTTPServer(HTTPServer):
    
        def __init__(self, *args, **kwargs) -> None:
            super().__init__(*args, **kwargs)
            self.ready_event = threading.Event()
    
        def service_actions(self):
            self.ready_event.set()
    
    
    with SignalingHTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
        thread = threading.Thread(target=httpd.serve_forever, daemon=True)
        thread.start()
        httpd.ready_event.wait()
        # Doing my work ...
        httpd.shutdown()