Skip to content

fix(cron): serialize get_due_jobs writes to prevent parallel state corruption - #19874

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-8c54fd4a
May 4, 2026
Merged

fix(cron): serialize get_due_jobs writes to prevent parallel state corruption#19874
teknium1 merged 1 commit into
mainfrom
hermes/hermes-8c54fd4a

Conversation

@teknium1

@teknium1 teknium1 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Salvage of #16509 onto current main.

Summary

get_due_jobs() called load_jobs() + conditional save_jobs() without holding _jobs_file_lock, creating a race with concurrent mark_job_run() and advance_next_run() calls from the scheduler tick thread. The race could clobber state when two cron cycles ran in parallel (gateway + systemd timer). Wrap get_due_jobs() body in _jobs_file_lock.

Validation

scripts/run_tests.sh tests/cron/test_jobs.py -k concurrent -> passed

Original PR: #16509

get_due_jobs() called load_jobs() and save_jobs() without holding
_jobs_file_lock, creating a race with the locked mark_job_run() and
advance_next_run(). Wrap get_due_jobs() with the lock (delegating to a
new _get_due_jobs_locked() inner function) so all load→modify→save
cycles are serialised. Add two regression tests: one verifying 3
concurrent mark_job_run() calls each land their correct last_status and
last_run_at without overwrites, and a stress test confirming 10 parallel
calls each increment their job's completed count to exactly 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@teknium1
teknium1 merged commit 1c7f47a into main May 4, 2026
2 of 3 checks passed
@teknium1
teknium1 deleted the hermes/hermes-8c54fd4a branch May 4, 2026 19:36
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cron Cron scheduler and job management labels May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants