@stonyx/cron 0.2.1-alpha.17 → 0.2.1-alpha.19
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.d.ts +8 -3
- package/dist/service.js +21 -9
- package/package.json +1 -1
package/dist/service.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ interface ListOptions {
|
|
|
28
28
|
}
|
|
29
29
|
type OnJobDueCallback = (job: Job) => Promise<JobDueResult | void> | JobDueResult | void;
|
|
30
30
|
export default class CronService {
|
|
31
|
+
#private;
|
|
31
32
|
jobs: Map<string, Job>;
|
|
32
33
|
heap: MinHeap<HeapEntry>;
|
|
33
34
|
timer: ReturnType<typeof setTimeout> | null;
|
|
@@ -91,10 +92,14 @@ export default class CronService {
|
|
|
91
92
|
* lock is what wedged every subsequent `locked()` call (add/update/remove)
|
|
92
93
|
* when a callback never settled.
|
|
93
94
|
*
|
|
94
|
-
* `
|
|
95
|
-
*
|
|
95
|
+
* `onTimer` performs the batch claim (findDueJobs + markRunning) for all due
|
|
96
|
+
* jobs under a single lock, then enters at phase 2 via `#executeClaimed`.
|
|
97
|
+
* That entry point is a `#private` method rather than a parameter on this
|
|
98
|
+
* one: as a published `alreadyClaimed` boolean it was a supported way for a
|
|
99
|
+
* consumer to skip phase 1 entirely, which defeats the claim guard AC4 asks
|
|
100
|
+
* for and allows concurrent `onJobDue` invocations for the same job.
|
|
96
101
|
*/
|
|
97
|
-
executeJob(job: Job
|
|
102
|
+
executeJob(job: Job): Promise<ExecuteResult>;
|
|
98
103
|
/**
|
|
99
104
|
* Phase 1 - claim. Must be called while holding the lock.
|
|
100
105
|
*
|
package/dist/service.js
CHANGED
|
@@ -210,7 +210,7 @@ export default class CronService {
|
|
|
210
210
|
// cannot poison the lock chain.
|
|
211
211
|
for (const job of dueJobs) {
|
|
212
212
|
try {
|
|
213
|
-
await this
|
|
213
|
+
await this.#executeClaimed(job);
|
|
214
214
|
}
|
|
215
215
|
catch (err) {
|
|
216
216
|
// One job's unexpected throw must not abort the batch. Every job in
|
|
@@ -262,16 +262,28 @@ export default class CronService {
|
|
|
262
262
|
* lock is what wedged every subsequent `locked()` call (add/update/remove)
|
|
263
263
|
* when a callback never settled.
|
|
264
264
|
*
|
|
265
|
-
* `
|
|
266
|
-
*
|
|
265
|
+
* `onTimer` performs the batch claim (findDueJobs + markRunning) for all due
|
|
266
|
+
* jobs under a single lock, then enters at phase 2 via `#executeClaimed`.
|
|
267
|
+
* That entry point is a `#private` method rather than a parameter on this
|
|
268
|
+
* one: as a published `alreadyClaimed` boolean it was a supported way for a
|
|
269
|
+
* consumer to skip phase 1 entirely, which defeats the claim guard AC4 asks
|
|
270
|
+
* for and allows concurrent `onJobDue` invocations for the same job.
|
|
267
271
|
*/
|
|
268
|
-
async executeJob(job
|
|
272
|
+
async executeJob(job) {
|
|
269
273
|
// -- Phase 1: claim (locked) --
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
const refusal = await locked(() => this.claimJob(job));
|
|
275
|
+
if (refusal)
|
|
276
|
+
return { status: 'skipped', reason: refusal };
|
|
277
|
+
return this.#executeClaimed(job);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Phases 2 and 3 for a job that has already been claimed - either by
|
|
281
|
+
* `executeJob` above or by `onTimer`'s batch claim.
|
|
282
|
+
*
|
|
283
|
+
* Private: reaching this without a claim would run the consumer callback for
|
|
284
|
+
* a job nobody owns.
|
|
285
|
+
*/
|
|
286
|
+
async #executeClaimed(job) {
|
|
275
287
|
// Membership re-check. The claim and the invoke are no longer in the same
|
|
276
288
|
// critical section, and sibling callbacks run unlocked, so a `remove()` can
|
|
277
289
|
// land in between AND RESOLVE - it used to deadlock. A resolved `remove()`
|