Commit ca48cf3
fix(service-job): leader-elect
* fix(service-job): leader-elect `type: 'once'` schedules on DbJobAdapter
`DbJobAdapter.schedule()` routed `once` registrations to `inner`
(`IntervalJobAdapter`), a bare `setTimeout` with no cluster lock anywhere in
that file, so a one-shot job ran once per replica instead of once per cluster
— the last limb left after #13686 did the same for `interval`, and the
worst-shaped of the three: a one-shot has no later tick during which a
business-level de-duplication marker could win.
Route `once` to `this.cron` (`CronJobAdapter`, whose own `once` branch already
fires through the leader-electing `runScheduled()`) when a cron adapter is
assembled, and keep the registration in `inner` via `register()` so
`trigger()`, `replay()`, `getExecutions()` and `listJobs()` are unaffected. No
cron adapter assembled => unchanged: `inner.schedule()`, as before.
Crash semantics are at-most-once per cluster, per the maintainer ruling of
2026-09-01, and stated in the docblock: no re-arm and no persistence is added.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
* chore(service-job): changeset for the `once` leader-election fix
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
* chore(scripts): record the new service-job engine double in the pinned ledger
`node scripts/check-engine-double-contract.mjs --write` — 1 row added, 0 lost:
the `update` double in the new `db-job-adapter.once-leader.test.ts`, which is
already routed through `assertEngineUpdateDispatch`. Coverage growth only.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
* test(service-job): let the #13918 card pin report all of today's evidence
The pin exists to state the card's repro: two replicas, one deadline, two
`sys_job_run` rows today and one after. A hard throw on the execution count
stops the run before the fence count and the row count are ever reported, so
the ablation that proves the pin can fail printed only the first of the three.
The three pre-row assertions are now soft; the row assertions stay hard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUF1NoViznQK32gqpK8wS8
---------
Co-authored-by: Claude <noreply@anthropic.com>type: 'once' schedules on DbJobAdapter (#14618)1 parent 10220a7 commit ca48cf3
4 files changed
Lines changed: 442 additions & 15 deletions
File tree
- .changeset
- packages/services/service-job/src
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
0 commit comments