fix(cron): execute job immediately on action=run instead of waiting for next tick (#41037) - #41269
fix(cron): execute job immediately on action=run instead of waiting for next tick (#41037)#41269rodboev wants to merge 1 commit into
Conversation
Review: advance_next_run race conditionThe The problemIn advance_next_run(job["id"]) # ← bumps next_run_at NOW
pool = _get_sequential_pool() if ...
def _run_and_release(j=job, ctx=_ctx):
try:
success, output, final_response, error = ctx.run(run_job, j)
...
except Exception as e:
mark_job_run(j["id"], False, str(e)) # ← failure pathIf the job fails (exception, agent timeout, empty response), Suggested fixMove def _run_and_release(j=job, ctx=_ctx):
try:
success, output, final_response, error = ctx.run(run_job, j)
if success:
advance_next_run(j["id"]) # ← only advance on success
...This preserves the double-execution guard (the job is already in NoteThe |
|
Addressed the follow-up issues in the manual-run / gateway-only path.
Validation:
|
9d5e344 to
26ee9cf
Compare
26ee9cf to
60851c1
Compare
667a08e to
0adcf9d
Compare
aa6e213 to
8262526
Compare
|
Closing this now. The linked issue was completed by merged PR #50025, and review also found an advance_next_run race in this older branch. |
Summary
cronjob(action="run")used to stampnext_run_atand rely on the next scheduler tick. That left CLI-only and Windows setups with a success response but no actual execution, and it made manual runs depend on whether a live gateway loop happened to be polling.This change dispatches manual runs through the scheduler execution path immediately. It preserves paused or future schedule state for one-off manual runs, queues delivery targets that need live gateway adapters for the next gateway tick, and shares the per-job run claim between manual dispatch and normal ticks so the same job is not double-fired across processes.
Changes
tools/cronjob_tools.py: routerunand its aliases through immediate dispatch, preserve schedule snapshots, and fall back to queueing when live delivery context is requiredcron/scheduler.py: add immediate-run helpers, manual-run schedule restore helpers, live-delivery checks, and shared per-job claim handling for both immediate runs and tick submissionshermes_cli/cron.py: updaterunoutput to report whether the job was dispatched now or queued for the next ticktests/tools/test_cronjob_run_immediate.py: cover immediate dispatch, live-context queueing, schedule restore, and already-running rejectiontests/cron/test_scheduler.py: cover the cross-process overlap where tick must skip a job already claimed by an immediate runValidation
action=run, no gateway tickeraction=run, gateway runningaction=run, live-adapter-only delivery with no live contextTest plan
python -m pytest tests/tools/test_cronjob_run_immediate.py -vpython -m pytest tests/cron/test_scheduler.py -k TestParallelTick -vFixes #41037