0

I have the following "main" code:

with  http.server.ThreadingHTTPServer( ("", port), Handler )  as daemon:
    print(f"serving on port {port} process {os.getpid()} ")
    while True:
        try:
            daemon.handle_request()
        except KeyboardInterrupt:
            print("\nexiting")
            return 0

which works great. However - this is only used for local testing and on the ci machine - so I want an easy way to shut it down and replace it with the next one - so inside the Handler do_GET(self) I added the following code:

   if path == "/shutdown":
       throw Exception("shut down")

and if I do a curl http://localhost:9000/shutdown.... I do indeed see an exception - nicely displayed and swallowed inside the thread.

And I've found it remarkably hard to figure out any way of stopping the server from inside the handler - because the handler is running in another process.

Is there a simple way of doing it?

Darren Oakey
  • 2,894
  • 3
  • 29
  • 55
  • I sort of found a way of doing it - which works basically, although I have to call shutdown twice - by adding a multiprocessing.Queue - reading it with no wait in the main loop, and putting something on it in the thing that implements basehttphandler - but it shouldn't be this hard? – Darren Oakey Jul 11 '22 at 10:58
  • I was thinking of a queue as well. That's a pretty common solution for multithread applications, and it's not that hard, is it? But I don't understand why you need to call shutdown twice. I think you only have to call it from the main loop, right? Maybe you can add the code to your question to clarify this... – wovano Jul 11 '22 at 11:57
  • By the way, an [Event](https://docs.python.org/3/library/threading.html#threading.Event) would probably be a better choice for this use case. – wovano Jul 11 '22 at 11:58
  • the reason why I have to call shutdown twice is that the daemon.handle_request is a blocking call that spawns a thread - ie by the time my shutdown is being processed - the _next_ handle_request is waiting around. So even though I can happily set a status, it doesn't get checked until the loop goes around again – Darren Oakey Jul 11 '22 at 12:40
  • yeah - event seems better than a queue - but doesn't stop me having to call it twice :( – Darren Oakey Jul 11 '22 at 12:41
  • I would expect that calling it once is enough. Even though the real shutdown might be delayed until the current request is being handled... By the way, did you also try to use `daemon.server_forever()` instead of `while True: daemon.handle_request()` ? This seems nicer, IMHO, and I wonder if this might affect the way the shutdown is handled, since the documentation mentions "_`shutdown()` must be called while `serve_forever()` is running in a different thread otherwise it will deadlock._" – wovano Jul 11 '22 at 12:59

0 Answers0