fix(cron): ensure ticker thread starts and monitor for death (#342) #345

Merged
Timmy merged 1 commits from fix/cron-ticker-startup into main 2026-04-13 07:15:30 +00:00

View File

@@ -7496,17 +7496,41 @@ async def start_gateway(config: Optional[GatewayConfig] = None, replace: bool =
# Start background cron ticker so scheduled jobs fire automatically.
# Pass the event loop so cron delivery can use live adapters (E2EE support).
cron_stop = threading.Event()
try:
_cron_loop = asyncio.get_running_loop()
except RuntimeError:
_cron_loop = None
logger.warning("No running event loop — cron ticker will run without adapter delivery")
cron_thread = threading.Thread(
target=_start_cron_ticker,
args=(cron_stop,),
kwargs={"adapters": runner.adapters, "loop": asyncio.get_running_loop()},
kwargs={"adapters": runner.adapters, "loop": _cron_loop},
daemon=True,
name="cron-ticker",
)
cron_thread.start()
logger.info("Cron ticker thread started (pid=%d, thread=%s)", os.getpid(), cron_thread.name)
# Monitor ticker thread — restart if it dies unexpectedly
async def _monitor_ticker():
while not cron_stop.is_set():
if not cron_thread.is_alive():
logger.warning("Cron ticker thread died — restarting")
cron_thread2 = threading.Thread(
target=_start_cron_ticker,
args=(cron_stop,),
kwargs={"adapters": runner.adapters, "loop": _cron_loop},
daemon=True,
name="cron-ticker-restart",
)
cron_thread2.start()
logger.info("Cron ticker thread restarted")
await asyncio.sleep(30)
monitor_task = asyncio.create_task(_monitor_ticker())
# Wait for shutdown
await runner.wait_for_shutdown()
monitor_task.cancel()
if runner.should_exit_with_failure:
if runner.exit_reason: