Skip to content

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

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

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

Conversation

@trungminhdo4-glitch

@trungminhdo4-glitch trungminhdo4-glitch commented Jul 30, 2026

Copy link
Copy Markdown

HUMAN: I reviewed the scheduler changes and tested the overlap guard locally. I checked that cron runs are skipped when the same automation already has a PENDING or RUNNING run, while terminal runs still allow the next cron run. I also checked the batch rotation, telemetry and timestamp behavior, and that manual/event triggered dispatch is not affected.
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.

@trungminhdo4-glitch
trungminhdo4-glitch marked this pull request as ready for review August 22, 2026 08:29
@all-hands-bot

Copy link
Copy Markdown
Contributor

👋 This PR needs a couple of things fixed before OpenHands can review it:

  • the PR description's HUMAN: section needs at least 20 characters describing what you tested, not just the template placeholder

Push an update once this is addressed and this check re-runs automatically.

This is an automated check - no AI was used to generate this comment.

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)

2 participants