Skip to content

start_gateway() skips cron ticker cleanup on failure shutdown #12175

@NewTurn2017

Description

@NewTurn2017

Summary

start_gateway() starts the background cron ticker thread, waits for shutdown, and then returns early on runner.should_exit_with_failure. That early return skips cron_stop.set() and cron_thread.join(...), leaving the cron ticker running after a failure exit path.

Affected code

  • gateway/run.py:8941-8963

Why this is a bug

On the failure shutdown path, start_gateway() returns False before executing the cron cleanup block. This leaks the daemon cron thread for embedded/test/library callers and can keep scheduled work firing until the process exits.

Minimal reproduction

# fake runner:
# - start() -> True
# - wait_for_shutdown() returns
# - should_exit_with_failure = True
# - exit_reason = "boom"

result = await start_gateway(None)
print(result, thread_started, thread_joined)
# actual: False, True, False

Observed with a patched fake thread:

  • thread_started = True
  • thread_joined = False

Expected behavior

  • The cron ticker should always be stopped/joined before start_gateway() returns, regardless of whether shutdown is clean or failure-driven.

Actual behavior

  • Failure exit returns before cleanup, so the ticker thread keeps running.

Suggested investigation

  • Move cron cleanup into a finally block after wait_for_shutdown() or otherwise guarantee cleanup on both clean and failure return paths.
  • Add a focused test for should_exit_with_failure=True that asserts the cron thread is joined.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/cronCron scheduler and job managementcomp/gatewayGateway runner, session dispatch, deliverytype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions