Consider a toy server serving a notification that it will quit in 5s at http://localhost:48555/q and 'Hello World' elsewhere.
from datetime import datetime
from http.server import HTTPServer, BaseHTTPRequestHandler
from threading import Thread
from time import sleep
from urllib.parse import urlparse
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
path =urlparse(self.path).path
response=f"{datetime.now()}: {'stopping server in 5s' if path=='/q' else 'Hello World!'}"
self.wfile.write(bytes(response, 'ascii'))
self.wfile.flush()
if path=='/q':
Thread(target=self.quit()).start()
def quit(self): # don't call on thread running the server
sleep(5)
self.server.shutdown()
address = ('localhost', 48555)
server = HTTPServer(address, Handler)
print(f'started a server on http://{address[0]}:{address[1]}')
server.serve_forever()
Despite calling self.server.shutdown() from a separate thread, the server doesn't shutdown correctly - the tab in the browser (Firefox 115.0.2) stays in loading state while the python environment keeps running. Also the response is never written to client in spite of the explicit flush.
Why is this happening?
I have tried making the thread daemon=True, removing the sleep altogether and replacing
server.shutdown with exit(). Only the last one actually shuts everything down, though the reponse is still served afterwards, not before the wait.