fix(controller,worker): dual-state worker loss + resend actual job state (bug-1509 P3)
Phase 3 (B1 dual-state + B2): a job never lingers as RUN when its worker is lost. Dual-state B1 (user-approved): RDHUP (worker TCP dropped = confirmed dead) marks its RUN jobs EXIT immediately (mark_worker_jobs_exit). Heartbeat timeout (unknown) keeps them UNKWN+TRANSIENT awaiting reconnect reconciliation; the TRANSIENT TTL GC is the backstop. handle_worker_leave now calls mark_worker_jobs_exit (was mark_worker_jobs_unknown in Phase 2). B2 (worker side): resend_job_status now checks the recovered process is alive (kill(pid,0)) before re-reporting RUN — a dead process is reported finished so the controller converges to EXIT instead of a stale RUN. And resend_job_status runs on EVERY rejoin (checking_connection), not just startup, so a reconnecting worker's jobs are reconciled (clears UNKWN via the existing notify_jobstart claim path). Design: docs/Job-Finish-Robustness-设计文档.md §4.4 (dual-state decision). Unit test: worker RDHUP marks jobs EXIT (not UNKWN).
This commit is contained in:
parent
fc091348e8
commit
d3a92f1033
7 changed files with 135 additions and 18 deletions
|
|
@ -1832,11 +1832,37 @@ static void test_restart_marks_all_run_jobs_unknown(void)
|
|||
printf("test_restart_marks_all_run_jobs_unknown: PASS\n");
|
||||
}
|
||||
|
||||
/* Phase 3 dual-state (B1): RDHUP (confirmed worker death) marks RUN jobs
|
||||
* EXIT immediately — distinct from the heartbeat-timeout path (UNKWN). */
|
||||
static void test_worker_rdhup_marks_jobs_exit(void)
|
||||
{
|
||||
tap_setup();
|
||||
|
||||
job_t* j = tap_seed_job(1007, JOB_STAT_RUN);
|
||||
TEST_ASSERT_NOT_NULL(j);
|
||||
lock(j, RTTI_LOCK_WRITE);
|
||||
tap_set_job_allocs(j, "t1");
|
||||
unlock(j);
|
||||
|
||||
mark_worker_jobs_exit(&g_tap_c, "t1");
|
||||
|
||||
TEST_ASSERT_TRUE_MESSAGE(j->job.state & JOB_STAT_EXIT,
|
||||
"job must be EXIT after confirmed worker death");
|
||||
TEST_ASSERT_FALSE_MESSAGE(j->job.state & JOB_STAT_UNKWN,
|
||||
"confirmed-dead path is EXIT, not UNKWN");
|
||||
TEST_ASSERT_TRUE_MESSAGE(j->job.finish_time > 0,
|
||||
"finish_time must be set");
|
||||
|
||||
tap_teardown();
|
||||
printf("test_worker_rdhup_marks_jobs_exit: PASS\n");
|
||||
}
|
||||
|
||||
/* ── Test group entry point ───────────────────────────────────────────── */
|
||||
|
||||
void test_apply_pump(void)
|
||||
{
|
||||
UnitySetTestFile(__FILE__);
|
||||
RUN_TEST(test_worker_rdhup_marks_jobs_exit);
|
||||
RUN_TEST(test_worker_loss_marks_its_run_jobs_unknown);
|
||||
RUN_TEST(test_worker_loss_does_not_touch_other_host_jobs);
|
||||
RUN_TEST(test_restart_marks_all_run_jobs_unknown);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue