xuhdev
xuhdev

Reputation: 9333

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?

Upvotes: 1

Views: 1212

Answers (1)

AKX
AKX

Reputation: 168913

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

Upvotes: 2

Related Questions