Use _stop_event consistently across all threads as the way to signal that it should stop. Add thread joins with timeouts to allow the program to exit cleanly

This commit is contained in:
Ian Renton
2026-09-18 09:21:38 +01:00
parent d79c8f72c8
commit 29d8654234
28 changed files with 239 additions and 126 deletions
+19 -8
View File
@@ -15,17 +15,25 @@ from webserver.webserver import WEB_SERVER
logger = logging.getLogger(__name__)
_shutdown_in_progress = False
def shutdown(_signum=None, _frame=None):
"""Shutdown function"""
# Check if this is the second time a shutdown was asked for, if so immediately kill the program.
global _shutdown_in_progress
if _shutdown_in_progress:
os._exit(1)
_shutdown_in_progress = True
logger.info("Stopping program...")
WEB_SERVER.stop()
TELNET_SERVER.stop()
DATA_PROVIDERS.stop()
CLEANUP_TIMER.stop()
DATA_STORE.close()
os._exit(0)
logger.info("Stopped.")
# Main function
@@ -43,8 +51,9 @@ if __name__ == "__main__":
logger.info("Starting...")
logger.info(f"This is Spothole version {SOFTWARE_VERSION}. This instance is run by {SERVER_OWNER_CALLSIGN}.")
# Shut down gracefully on SIGINT
# Shut down gracefully on SIGINT or SIGTERM
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)
# Set up data store
DATA_STORE.setup()
@@ -59,14 +68,16 @@ if __name__ == "__main__":
status_reporter = StatusReporter(run_interval=5)
status_reporter.start()
# Set up the web server
WEB_SERVER.setup()
# Run the telnet server
if TELNET_SERVER_ENABLED:
TELNET_SERVER.start(port=TELNET_SERVER_PORT)
# Run the web server. This is the blocking call that keeps the application running in the main thread, so this must
# be the last thing we do. web_server.stop() triggers an await condition in the web server which finishes the main
# thread.
# Set up the web server
WEB_SERVER.setup()
# Run the web server
WEB_SERVER.start()
# Block the main thread until a termination signal arrives and shutdown() is running.
while not _shutdown_in_progress:
signal.pause()