feat(worker-rejoin-resync): apply reported outcomes idempotently (task 3.2)
Add resync_apply_report()/resync_apply_running_entry()/ resync_apply_finished_entry()/resync_apply_unrecognized_entry() to resync.c: routes each entry in a worker's job-state report to the correct existing idempotent path (still-running -> clear from outstanding set, no fact; finished-success/failure -> record_job_finish_fact_at/ on_job_fail; unrecognized -> record_job_reconcile_pending_fact; unqueried extra -> record_job_reconcile_assign_fact or no-op), discards reports for superseded rounds (Req 6.1/6.3), and resolves the round once its outstanding set empties. Also fixes bug-1747 (Req 4.2): adds record_job_finish_fact_at(), additive alongside the unmodified record_job_finish_fact, so a finished-success reconciliation entry records the WORKER-reported finish time instead of reconciliation-processing time -- proven via a real WAL-write + persist_recover() restart-replay test. The FAIL-side half of the same gap (WAL_JOB_FAIL carries no fail-time wire slot at all, for any caller) is confirmed pre-existing and systemic, correctly left out of this task's scope. Three review rounds surfaced and fixed two real, distinct bugs in the unqueried-extra-job routing guard (see tasks.md's Implementation Notes for the full account and the general lesson about re-deriving a full truth table after a partial boolean-guard fix): round 1 caught the wrong axis (terminal-vs-non-terminal instead of assignment-status, Req 4.8); round 2 caught that the first fix's short-circuit clobbered an already-terminal job's DONE/EXIT back to RUN (Req 4.4), including confirming the implementer's own test had certified the bug as correct; round 3 independently re-derived the final three-way guard from scratch and found no further defect. bug-1748 logged for the guard fix. Full controller suite: 1239 tests, 0 failures. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y4M5MJM2zK6nU43da267Ku
This commit is contained in:
parent
442fcf4544
commit
eec2596c5d
8 changed files with 1600 additions and 7 deletions
|
|
@ -241,6 +241,28 @@ extern int record_job_reconcile_pending_fact(cluster_t*, job_t*);
|
|||
extern int record_job_reconcile_assign_fact(cluster_t*, job_t*, worker_t*,
|
||||
xce_job_state_entry_t*);
|
||||
|
||||
/* worker-rejoin-resync task 3.2 (bug-1747 fix, Req 4.2): record_job_finish_
|
||||
* fact()'s worker-reported-finish-time sibling, for the reconciliation
|
||||
* finished-success path only. Same body/guard/hook-fire/deferred-append
|
||||
* pattern as record_job_finish_fact() (job.c, unmodified) -- differs only
|
||||
* in passing `finish_time_ms` (converted ms -> s) to persist_submit_job_
|
||||
* finish_fact() instead of time(NULL). See job.c's own doc comment on this
|
||||
* function for the full rationale, including the persist_submit_job_
|
||||
* finish_fact() unit confirmation.
|
||||
*
|
||||
* Precondition: caller holds `job` under RTTI_LOCK_WRITE on entry and keeps
|
||||
* holding it until this call returns -- this function does not lock/unlock
|
||||
* `job` itself, matching record_job_finish_fact's own convention.
|
||||
*
|
||||
* DEFERRED pattern (unlike record_job_reconcile_pending_fact/assign_fact
|
||||
* above): this function only durably appends the fact; it does NOT mutate
|
||||
* job's in-memory state and the caller must NOT call persist_notify_job_
|
||||
* updated_already_persisted() afterward -- exactly like record_job_finish_
|
||||
* fact(), the mutation and notify happen later, via apply_committed_entry's
|
||||
* replay of the committed WAL_JOB_FINISH entry. */
|
||||
extern int record_job_finish_fact_at(cluster_t*, job_t*, xce_jobfinish_t*,
|
||||
uint64_t);
|
||||
|
||||
extern int on_job_start(cluster_t*, job_pidinfo_t*);
|
||||
extern int on_job_finish(cluster_t*, xce_jobfinish_t*);
|
||||
extern int on_job_fail(cluster_t*, job_failinfo_t*);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue