fix(neuron): clone id/model_id before TP spawn so wire projector can use them
Some checks failed
build-prerelease / Package helexa-neuron-ada RPM (push) Blocked by required conditions
build-prerelease / Package helexa-neuron-ampere RPM (push) Blocked by required conditions
build-prerelease / Package helexa-neuron-blackwell RPM (push) Blocked by required conditions
CI / Format (push) Successful in 39s
build-prerelease / Resolve version stamps (push) Successful in 40s
CI / Clippy (push) Successful in 2m34s
CI / Test (push) Successful in 5m40s
build-prerelease / Build cortex binary (push) Successful in 5m16s
CI / Build cortex SRPM (push) Has been skipped
CI / Publish cortex to COPR (push) Has been skipped
CI / Build neuron SRPM (push) Has been skipped
CI / Publish neuron to COPR (push) Has been skipped
CI / Bump version in source (push) Has been skipped
build-prerelease / Build neuron-blackwell (push) Successful in 5m49s
build-prerelease / Package cortex RPM (push) Successful in 1m25s
build-prerelease / Build neuron-ampere (push) Successful in 7m38s
build-prerelease / Build neuron-ada (push) Successful in 5m34s
build-prerelease / Publish to rpm.lair.cafe (unstable) (push) Has been cancelled

The Step 1 refactor moved the InferenceEvent receiver wrap to *after*
the orchestration spawn in chat_completion_tp_stream, but the spawn
moves both `id` and `model_id` into its async closure (used heavily
by acquire_pool_lock, NCCL ops, and tracing). Result: borrowck
error E0382 use-of-moved-value on the wire_chat::project_chat_stream
call.

The non-CUDA build doesn't exercise this branch (it lives behind
`#[cfg(feature = "cuda")]`) which is why the workspace clippy/test
gate passed locally and on the regular CI workflow. The RPM build
workflow, which compiles with --features cuda, caught it (run 244
jobs 2/3/4 against beast / ampere / ada respectively, all the same
error).

Fix: snapshot `id` and `model_id` into `projector_id` /
`projector_model_id` before the spawn, use those at the projector
call site. The originals stay free to be moved into the closure.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 09:37:10 +03:00
parent 302ccfb982
commit 6927286cab

View File

@@ -2265,6 +2265,13 @@ impl CandleHarness {
let id = format!("chatcmpl-{:x}", unix_subsec_nanos()); let id = format!("chatcmpl-{:x}", unix_subsec_nanos());
let created = unix_now_secs(); let created = unix_now_secs();
let tokenizer = tp.tokenizer.clone(); let tokenizer = tp.tokenizer.clone();
// The spawned orchestration task below consumes both `id`
// and `model_id` (tracing, pool lookups, NCCL ops use them
// heavily). The wire projector at the bottom of this fn
// also needs them to stamp request metadata onto every
// chunk. Clone here so each side owns its copy.
let projector_id = id.clone();
let projector_model_id = model_id.clone();
// Bounded channel — back-pressures the producer when // Bounded channel — back-pressures the producer when
// downstream consumption (wire projector → SSE writer) is // downstream consumption (wire projector → SSE writer) is
@@ -2537,8 +2544,11 @@ impl CandleHarness {
// Wrap the InferenceEvent receiver in the OpenAI chat // Wrap the InferenceEvent receiver in the OpenAI chat
// projection so the HTTP handler keeps consuming // projection so the HTTP handler keeps consuming
// ChatCompletionChunks unchanged. // ChatCompletionChunks unchanged. Uses the clones we
let rx = wire_chat::project_chat_stream(event_rx, id, created, model_id); // stashed before the spawn — the originals were moved
// into the orchestration task above.
let rx =
wire_chat::project_chat_stream(event_rx, projector_id, created, projector_model_id);
Ok(rx) Ok(rx)
} }
} }