@stonyx/cron 0.2.1-alpha.16 → 0.2.1-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/service.js +47 -34
- package/package.json +1 -1
package/dist/service.js
CHANGED
|
@@ -344,45 +344,58 @@ export default class CronService {
|
|
|
344
344
|
* Phase 3 - settle. Must be called while holding the lock.
|
|
345
345
|
*/
|
|
346
346
|
settleJob(job, status, error, summary, startMs, durationMs) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
347
|
+
try {
|
|
348
|
+
const validStatus = (status === 'ok' || status === 'error' || status === 'skipped') ? status : 'error';
|
|
349
|
+
applyResult(job, validStatus, error, durationMs);
|
|
350
|
+
// The callback ran unlocked, so this job may have been removed - or
|
|
351
|
+
// removed and re-registered under the same id (the shape
|
|
352
|
+
// `start(initialJobs)` uses) - while it was in flight. Identity, not id.
|
|
353
|
+
//
|
|
354
|
+
// Deliberately touch NOTHING here. The claim phase already detached this
|
|
355
|
+
// job's own heap entry and nothing re-added it, so there is nothing to
|
|
356
|
+
// clean up; any entry now filed under this id belongs to the
|
|
357
|
+
// replacement, and removing it by id would silently unschedule a live
|
|
358
|
+
// job. Do not resurrect a removed job's heap entry or run log either.
|
|
359
|
+
if (this.jobs.get(job.id) !== job) {
|
|
360
|
+
return { status, error, summary, durationMs };
|
|
361
|
+
}
|
|
362
|
+
// Log the run
|
|
363
|
+
this.runLog.record({
|
|
364
|
+
jobId: job.id,
|
|
365
|
+
status,
|
|
366
|
+
error,
|
|
367
|
+
summary,
|
|
368
|
+
runAtMs: startMs,
|
|
369
|
+
durationMs,
|
|
370
|
+
nextRunAtMs: job.state.nextRunAtMs,
|
|
371
|
+
});
|
|
372
|
+
// Handle one-shot auto-delete. The callback ran unlocked and may have
|
|
373
|
+
// pushed a heap entry for this job via update(), so drop it - the job is
|
|
374
|
+
// about to stop existing.
|
|
375
|
+
if (job.deleteAfterRun && status === 'ok' && !job.enabled) {
|
|
376
|
+
this.jobs.delete(job.id);
|
|
377
|
+
this.removeFromHeap(job.id);
|
|
378
|
+
this.runLog.removeJob(job.id);
|
|
379
|
+
return { status, summary, deleted: true };
|
|
380
|
+
}
|
|
381
|
+
// Re-insert into heap if still active. The callback ran unlocked, so it
|
|
382
|
+
// may itself have added a heap entry for this job (via add/update); drop
|
|
383
|
+
// any such entry first to preserve one-entry-per-key.
|
|
352
384
|
this.removeFromHeap(job.id);
|
|
353
|
-
|
|
385
|
+
if (job.enabled && job.state.nextRunAtMs) {
|
|
386
|
+
this.heap.push({ key: job.id, nextTrigger: job.state.nextRunAtMs });
|
|
387
|
+
}
|
|
354
388
|
return { status, error, summary, durationMs };
|
|
355
389
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
durationMs,
|
|
364
|
-
nextRunAtMs: job.state.nextRunAtMs,
|
|
365
|
-
});
|
|
366
|
-
// Handle one-shot auto-delete
|
|
367
|
-
if (job.deleteAfterRun && status === 'ok' && !job.enabled) {
|
|
368
|
-
this.jobs.delete(job.id);
|
|
369
|
-
this.removeFromHeap(job.id);
|
|
370
|
-
this.runLog.removeJob(job.id);
|
|
390
|
+
finally {
|
|
391
|
+
// One re-arm covering every exit, rather than one per branch. The claim
|
|
392
|
+
// phase detached this job from the heap, so a timer that fired during the
|
|
393
|
+
// unlocked invoke would have found an empty heap and armed nothing -
|
|
394
|
+
// and `run()` has no `finally { armTimer() }` of its own the way
|
|
395
|
+
// `onTimer` does. Without this a manual run() can leave the scheduler
|
|
396
|
+
// with no pending wake at all.
|
|
371
397
|
this.armTimer();
|
|
372
|
-
return { status, summary, deleted: true };
|
|
373
398
|
}
|
|
374
|
-
// Re-insert into heap if still active. The callback ran unlocked, so it
|
|
375
|
-
// may itself have added a heap entry for this job (via add/update); drop
|
|
376
|
-
// any such entry first to preserve one-entry-per-key.
|
|
377
|
-
this.removeFromHeap(job.id);
|
|
378
|
-
if (job.enabled && job.state.nextRunAtMs) {
|
|
379
|
-
this.heap.push({ key: job.id, nextTrigger: job.state.nextRunAtMs });
|
|
380
|
-
}
|
|
381
|
-
// The claim phase detached this job from the heap, so a timer that fired
|
|
382
|
-
// during the unlocked invoke would have seen it missing. Re-arm here so a
|
|
383
|
-
// manual run() can never leave the scheduler without a pending wake.
|
|
384
|
-
this.armTimer();
|
|
385
|
-
return { status, error, summary, durationMs };
|
|
386
399
|
}
|
|
387
400
|
// -- Helpers ---------------------------------------------------------
|
|
388
401
|
removeFromHeap(id) {
|