QTZPOC-20
QTZPOC-20: Improve worker shutdown handling by allowing SystemExit and KeyboardInterrupt to propagate directly, preserving their original exit codes and ensuring cleanup.
This commit is contained in:
@@ -305,23 +305,23 @@ async def main():
|
||||
# This will run the workers and wait for them to complete.
|
||||
# If an exception occurs in any of the worker handlers, it will be propagated here.
|
||||
await asyncio.gather(*handlers)
|
||||
except (SystemExit, KeyboardInterrupt) as e:
|
||||
# Deliberate shutdown (Ctrl+C, a handler's own sys.exit) — not a failure to log as one.
|
||||
# `finally` below calls sys.exit(exit_code) unconditionally, which supersedes this raise
|
||||
# and becomes the exception that actually propagates — the raise is here so this branch
|
||||
# still honors the reraise-on-SystemExit contract, not because it changes what exits.
|
||||
exit_code = e.code if isinstance(e, SystemExit) and isinstance(e.code, int) else 0
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.custom_error(f'An unhandled exception occurred: {e}', metadata_runtime)
|
||||
exit_code = 1
|
||||
finally:
|
||||
# No `except (SystemExit, KeyboardInterrupt)` on purpose: `finally` runs on every path,
|
||||
# caught or not, so cleanup still happens for a deliberate shutdown (Ctrl+C, a handler's
|
||||
# own sys.exit) without us having to catch and re-raise it ourselves — which would only
|
||||
# let us relabel its exit code before `sys.exit(exit_code)` below discards it anyway.
|
||||
# Letting it propagate on its own keeps the original code (e.g. a handler's sys.exit(N))
|
||||
# intact instead of collapsing it to 0.
|
||||
if notification_handler:
|
||||
notification_handler.shutdown()
|
||||
if activities:
|
||||
await activities.shutdown()
|
||||
metrics.APP_UP.labels(pod_id=POD_ID).set(0) # Mark app as DOWN
|
||||
sys.exit(exit_code)
|
||||
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
def start_prometheus_server(logger, metadata: dict):
|
||||
|
||||
Reference in New Issue
Block a user