Stopping Python socketserver.ThreadingTCPServer On Keyboard Interrupt
Curiously enough, Python documentation suggests writing async TCP server using mixins (see https://docs.python.org/3/library/socketserver.html#socketserver.ThreadingMixIn) while there's existing class that does it already hence not requiring boilerplate code - ant it's socketserver.ThreadingTCPServer.
Its usage is pretty much like socketserver.TCPServer in the documentation - here's an echo-like server example:
class TCPServerHandler(socketserver.StreamRequestHandler): def handle(self): data_line: str = "_" data_processor = DataProcess() while data_line: data_line = self.rfile.readline().strip().decode('ascii') if data_line == '.': print("Connection terminated by client request") self.finish() return self.request.sendall(data_line) with socketserver.ThreadingTCPServer(("localhost", 5000), TCPServerHandler) as server: try: server.daemon_threads = True server.serve_forever() except (KeyboardInterrupt, SystemExit): log.error("Shutdown signal received") finally: print('Stopping server') server.server_close()
Stopping the server
And it's all nice and fine, with one exception - the using code from the documentation doesn't stop on the keyboard interrupt. Which is annoying as the search for the problem brings many (valid) discussions on how the keyboard events are relevant to the main thread only so the server isn't responsible for it, but there was no valid solution - setting the recommended server.daemon = True flag did nothing.
The solution was surprisingly simple and intuitive, but not really described anywhere - to use the server.daemon_threads = True flag instead! Oh well...
I'll leave it here in case it pops up in someone's search and helps with the problem.