Skip to content

fix(router): keep RawBody's fast path when an insert changes nothing - #2663

Merged
slin1237 merged 1 commit into
mainfrom
fix/raw-body-noop-insert
Sep 23, 2026
Merged

slin1237 merged 1 commit into
mainfrom
fix/raw-body-noop-insert

Conversation

@hello-alexmcc

Copy link
Copy Markdown
Collaborator

Description

Problem

From the review of #2641: RawBody::insert always sets mutated = true, even when the value is unchanged. The PD prefill leg sets stream: false unconditionally, so every non-streaming PD request, whose body already carries stream: false, was marked mutated and re-serialized instead of going out as the bytes it was parsed from: the fast path #2641 introduced never applied to exactly the requests it was meant for.

Solution

An insert of the value already present (compared as raw JSON text) returns without marking the body. Everything else about insert is unchanged: an existing field keeps its position, a new one goes last.

Not done from that review, on purpose: the duplicate-top-level-key dedupe and adversarial case table (the input is serde output of a typed struct, so a duplicate key is unreachable, as the review itself notes) and a friendlier non-object error text (serde's is clear).

Test Plan

  • insert_of_an_unchanged_value_does_not_mark_the_body: stream:false inserted into a body carrying it leaves mutated() false; a different value marks it (watched fail first).
  • cargo test -p smg --lib -- request_body pd_router: 46 passed. cargo +nightly fmt --all -- --check clean; cargo clippy -p smg --all-targets -- -D warnings clean (without --all-features, no OpenCV here).
Checklist
  • cargo +nightly fmt passes
  • cargo clippy --all-targets -- -D warnings passes (without --all-features, see above)
  • (Optional) Documentation updated
  • (Optional) Please join us on Slack #sig-smg to discuss, review, and merge PRs

RawBody::insert marked the body mutated even when the value it set was
already there, so the prefill leg's unconditional stream:false on a
non-streaming request re-serialized a body its parsed bytes could
have served as they were, defeating the fast path #2641 introduced.
An insert of the value already present now leaves the body unmutated.

Signed-off-by: Alex McC <319643551+hello-alexmcc@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: fe93c1f4-13e6-4003-ac79-1b396f8fb778

📥 Commits

Reviewing files that changed from the base of the PR and between dceb98c and d628d05.

📒 Files selected for processing (1)
  • model_gateway/src/routers/http/request_body.rs

Limit details: You’ve used all 6 included reviews currently available. Your 47 included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Request bodies now remain unchanged when a field is set to its existing value, while updates to different values continue to take effect. This prevents unnecessary changes when resubmitting an unchanged setting.

Walkthrough

RawBody::insert now leaves the body unmutated when the existing raw JSON matches the inserted value. A test checks unchanged and changed stream values.

Changes

Raw body insertion

Layer / File(s) Summary
Skip unchanged raw JSON
model_gateway/src/routers/http/request_body.rs
RawBody::insert skips replacing a value when its raw JSON matches the existing field. The test verifies that inserting stream: false leaves the body unmutated and changing it to true marks it mutated.

Estimated code review effort: 2 (Simple) | ~8 minutes

Merge Risk: ⚪ Minimal · up to d628d

Unchanged raw values retain the original request bytes, while changed values continue to be applied. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes restoring the RawBody fast path when an insert does not change the value.
Description check ✅ Passed The description directly explains the mutation bug, the RawBody::insert fix, preserved behavior, and test results.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the model-gateway Model gateway crate changes label Sep 23, 2026
@claude

claude Bot commented Sep 23, 2026

Copy link
Copy Markdown

👋 The PR description doesn't fully follow
PULL_REQUEST_TEMPLATE.md:

  • Missing header: ## Changes

Please update the PR description so reviewers have the context they need.

Comment on lines +606 to +608
/// The prefill leg always sets `stream: false`; a non-streaming request
/// already carries it, and marking the body mutated for that re-serialized
/// a body the parsed bytes could have served as they were.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Nit: This comment (and the PR description) misstates the mechanism it fixes. In pd_router.rs, the prefill leg's bytes are always produced by prefill_body.to_bytes(..) (pd_router.rs:557) — there is no parsed-bytes reuse gated on mutated() for that leg. The stream: false insert (pd_router.rs:1015) lands on the prefill_body clone, never on the body whose mutated() gates the decode leg's fast path (pd_router.rs:562), and sanitize_prefill_for_kv_handoff unconditionally caps max_tokens/max_output_tokens to 1, so the prefill leg is genuinely mutated for nearly every request regardless of stream.

The insert precision fix is worthwhile hardening of the mutated invariant, but as written no current call site regains a fast path from it — realizing the described win would also need pd_router to gate the prefill bytes on prefill_body.mutated(). Consider rewording this comment (and the description) so future readers don't go looking for a fast path that isn't wired up.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the RawBody::insert change and traced all call sites (serialize_request_body, inject_bootstrap, inject_dp_rank, sanitize_prefill_for_kv_handoff, the kv-handoff decode insert). The equality check is correct: raw-text comparison is conservative (a semantically-equal-but-differently-formatted value still marks the body, which only costs a re-serialization), the mutated flag stays monotonic, and byte output is unchanged in every case. The new test covers both the no-op and the changed-value branch.

Summary: 0 🔴 Important, 1 🟡 Nit (the test's doc comment and PR description claim a prefill-leg fast path that no current call site is wired to), 0 🟣 Pre-existing.

@slin1237
slin1237 merged commit d8dba30 into main Sep 23, 2026
21 of 42 checks passed
@slin1237
slin1237 deleted the fix/raw-body-noop-insert branch September 23, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

model-gateway Model gateway crate changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants