fix(libxce): bug-1425 -- populate jobsubmit's *jobid on idempotent-replay success
xcecli_jobsubmit() could return rc>=0 (success) while leaving its *jobid output parameter at 0, reproducible under concurrent client load immediately after a fresh single-node election (~1-3/9 clients per round in the original repro). Root cause: XCECLI_FAILOVER_CALL's idempotent-replay rule (client_failover.c's xce_failover_classify) normalizes a retried resend that hits the server's EEXIST/inflight-collision rejection into overall success -- but that rejection reply carries no payload (handle_jobsubmit's EEXIST branches reply with RequestReply_data_nodata, job.c), so xce_jobsubmit() never populates *jobid on the winning attempt, nor did it on the earlier failing attempt (raw status was already negative). Adds jobsubmit_finalize_jobid() (client_internal.h/client.c), called from xcecli_jobsubmit() right after XCECLI_FAILOVER_CALL returns. Sets *jobid = submit->jobid (the client-generated id already on the wire -- the controller commits/echoes this exact value on every genuine success reply, bug-786/job.c:1439) whenever the overall call succeeded, otherwise leaves it untouched. Placed at the jobsubmit-specific wrapper layer, not the generic classify/decide layer, which stays fully generic. 3 new socket-free unit tests in test_libxce_retry.c (following this codebase's direct-state-simulation style for I/O-adjacent logic). Live-validated: full ASAN rebuild clean, libxce test suite 1/1 OK with all 3 new tests passing, and a 5-round/45-client concurrent-submit repro against a live single-node cluster showed 0 "no clean ack" failures (vs. 1-3/9 per round pre-fix). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
b33f8b68a6
commit
8a6c339a55
3 changed files with 95 additions and 2 deletions
|
|
@ -323,6 +323,15 @@ int xcecli_jobdispatch(xcecli_ctx_t c, xce_job_dispatch_t* info)
|
|||
xce_jobdispatch(&(ctx->ctx), info));
|
||||
}
|
||||
|
||||
/* bug-1425: see the doc comment on the declaration in client_internal.h for
|
||||
* the full mechanism this closes. */
|
||||
void jobsubmit_finalize_jobid(uint64_t* jobid, uint64_t submitted_jobid,
|
||||
int overall_rc)
|
||||
{
|
||||
if (jobid != NULL && overall_rc >= 0)
|
||||
*jobid = submitted_jobid;
|
||||
}
|
||||
|
||||
int xcecli_jobsubmit(xcecli_ctx_t c, xce_job_submit_t* submit, uint64_t* jobid)
|
||||
{
|
||||
api_ctx_t* ctx = (api_ctx_t*)c;
|
||||
|
|
@ -331,8 +340,10 @@ int xcecli_jobsubmit(xcecli_ctx_t c, xce_job_submit_t* submit, uint64_t* jobid)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return XCECLI_FAILOVER_CALL(ctx, /*is_write=*/true,
|
||||
xce_jobsubmit(&(ctx->ctx), submit, jobid));
|
||||
int rc = XCECLI_FAILOVER_CALL(ctx, /*is_write=*/true,
|
||||
xce_jobsubmit(&(ctx->ctx), submit, jobid));
|
||||
jobsubmit_finalize_jobid(jobid, submit->jobid, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xcecli_joblist(xcecli_ctx_t c, xce_job_t*** jobs)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue