mirror of
https://github.com/hansjone/dsh-ops-cron.git
synced 2026-10-09 00:43:22 +08:00
Fix one-shot jobs that never auto-fire after restart or slow ticks.
recover was clearing past-due at nextRunAt via nextFire→null; keep and re-arm them, and evaluate schedule misfire at tick start so a slow prior job cannot age peers out of grace. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
8cf624ce7f
commit
b22048d377
2 changed files with 82 additions and 3 deletions
17
lib/host.js
17
lib/host.js
|
|
@ -842,9 +842,9 @@ export function createHostService(options = {}) {
|
|||
return state.settings
|
||||
}
|
||||
|
||||
async function dispatchRun(jobId, trigger) {
|
||||
async function dispatchRun(jobId, trigger, opts = {}) {
|
||||
let claimed
|
||||
const t = now()
|
||||
const t = Number.isFinite(opts.at) ? opts.at : now()
|
||||
await withState((current) => {
|
||||
claimed = claimOccurrence(current, jobId, t, trigger, current.settings)
|
||||
if (claimed.decision.action === 'wait') return current
|
||||
|
|
@ -897,7 +897,9 @@ export function createHostService(options = {}) {
|
|||
misfirePolicy: state.settings.misfirePolicy,
|
||||
})
|
||||
if (decision.action === 'wait') continue
|
||||
const result = await dispatchRun(job.id, 'schedule')
|
||||
// Use tick start time for claim/misfire so a slow earlier job cannot
|
||||
// push later oneshots past the grace window.
|
||||
const result = await dispatchRun(job.id, 'schedule', { at: t })
|
||||
if (result.run) fired.push(result)
|
||||
}
|
||||
await tickWatcherReports()
|
||||
|
|
@ -967,6 +969,15 @@ export function createHostService(options = {}) {
|
|||
try {
|
||||
if (job.nextRunAt === null) return job
|
||||
if (Number.isFinite(job.nextRunAt) && job.nextRunAt > t) return job
|
||||
// Past-due one-shot: do NOT call nextFire (that returns null and
|
||||
// permanently kills the job). Re-arm to now so the next tick fires
|
||||
// a catch-up run instead of wiping or grace-misfiring after restart.
|
||||
if (job.schedule?.kind === 'at') {
|
||||
if (Number.isFinite(job.nextRunAt) && job.nextRunAt <= t) {
|
||||
return { ...job, nextRunAt: t }
|
||||
}
|
||||
return job
|
||||
}
|
||||
const nextRunAt = nextFire(job.schedule, t, job.schedule?.timezone || next.settings.timezone)
|
||||
return { ...job, nextRunAt }
|
||||
} catch {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue