Skip to content

fix(scheduler): skip cron runs while an automation is active - #283

Draft
trungminhdo4-glitch wants to merge 2 commits into
OpenHands:mainfrom
trungminhdo4-glitch:fix/issue-218-cron-overlap-guard
Draft

fix(scheduler): skip cron runs while an automation is active#283
trungminhdo4-glitch wants to merge 2 commits into
OpenHands:mainfrom
trungminhdo4-glitch:fix/issue-218-cron-overlap-guard

Conversation

@trungminhdo4-glitch

Copy link
Copy Markdown

Summary

  • skip cron-triggered run creation when the same automation already has a
    PENDING or RUNNING run
  • preserve normal scheduling after terminal runs
  • keep manual and event-triggered dispatch behavior unchanged
  • preserve scheduler polling fairness and telemetry semantics

Why

A cron automation can currently schedule another run while its previous run is
still pending or running. Long-running automations can therefore stack multiple
concurrent sandboxes.

Concurrency contract

The guard is evaluated inside the scheduler transaction that already locks the
automation row with FOR UPDATE SKIP LOCKED on PostgreSQL.

This PR intentionally applies the guard only to cron scheduling. Manual and
event-triggered dispatch behavior remains unchanged, and no database uniqueness
constraint is introduced, leaving room for an explicit per-automation override
later.

SQLite remains covered under the repository's existing single-process
assumption.

Behavior

Blocking statuses:

  • PENDING
  • RUNNING

Non-blocking statuses:

  • COMPLETED
  • FAILED
  • CANCELLED
  • SKIPPED

When a run is skipped:

  • last_polled_at is still updated
  • last_triggered_at is unchanged
  • no run row is created
  • no scheduled/created telemetry event is emitted

Tests

  • scheduler regression tests covering active and terminal statuses
  • mixed-automation, single-batch-query, and batch-rotation cases
  • telemetry and timestamp semantics
  • Ruff check
  • Ruff format check
  • Python compilation check

The functional behavior was tested with in-memory SQLite. PostgreSQL
multi-worker behavior was not exercised against a live PostgreSQL instance; the
serialization property follows the scheduler's existing automation-row lock.

Fixes #218

Disclosure: This contribution was prepared with AI assistance and independently
reviewed and tested locally before publication.

@github-actions github-actions Bot added the type: fix A bug fix label Jul 30, 2026
@trungminhdo4-glitch

Copy link
Copy Markdown
Author

HUMAN: (Owner-authorized; posted by my agent on my behalf.)

I am supervising this contribution, and it remains a draft by design. Before I decide it is ready for review, I want the concurrency contract to remain explicit: one batch query for due automations; PENDING and RUNNING block cron scheduling only; a skip updates last_polled_at without changing last_triggered_at or emitting scheduled/created telemetry; PostgreSQL relies on the existing automation-row lock, while SQLite retains its single-process assumption. The two lightweight PR checks pass; the four full fork workflows remain action_required and require maintainer approval before they can run. I will make the final ready-for-review and requested-change decisions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a minimal per-automation overlap guard (skip when a run is already in-flight)

1 participant