Skip to content

Scheduled jobs missed when bot is busy processing a message #174

@sakhnenkoff

Description

@sakhnenkoff

Problem

When a scheduled job fires while the bot is actively processing a user message (which can take several minutes via claude.run_command()), the event bus blocks and the scheduled job either gets delayed significantly or missed entirely.

I observed heartbeat jobs being missed by 8+ minutes because AgentHandler.handle_scheduled awaits claude.run_command() synchronously, which blocks EventBus._process_events from processing any subsequent events until the Claude execution finishes.

APScheduler logs: "Run time of job Heartbeat was missed by 0:08:54"

Root Cause

AgentHandler.handle_scheduled (in src/events/handlers.py) calls await self.claude.run_command(...) directly. Since the event bus dispatches events sequentially via _dispatch, a long-running Claude execution blocks the entire bus.

Proposed Fix

Change handle_scheduled to dispatch work via asyncio.create_task() and return immediately. This keeps the event bus sequential (safe) while scheduled jobs run in the background.

Key elements:

  • asyncio.create_task() + return immediately from handle_scheduled
  • asyncio.Semaphore(2) to cap concurrent Claude executions
  • task.add_done_callback() for cleanup and error logging
  • handle_webhook stays unchanged (webhooks are fast, blocking is fine)

I have a working implementation with tests — happy to open a PR if this approach looks right.

Environment

  • claude-code-telegram v1.6.0
  • APScheduler 3.11.x
  • Multiple scheduled jobs (heartbeats every 4h, morning briefing, weekly digest)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions