perf(node): avoid per-message DataType clone in first-message type check - #2838
Merged
trunk-io[bot] merged 1 commit intoJul 28, 2026
Merged
Conversation
The first-message input type check ran on both receive paths (`recv_async` and `Stream::poll_next`) as two copy-pasted blocks that each did `self.input_type_checks.get(id).cloned()` *before* deciding whether the message was pattern-correlated. For service/action inputs the check stays armed indefinitely (those inputs are polymorphic by pattern design), so the stored `DataType` — which can be a nested `Struct`/`List` — was cloned and then discarded on *every* message on that input. Consolidate both paths into one `note_produced_event` helper and order the guard so it is cheap in every case: 1. `input_type_checks.contains_key(id)` — a single map lookup that short-circuits once the check has been consumed, preserving the existing "zero extra cost after the first message per input" property for steady-state topic traffic. 2. `carries_pattern_correlation(...)` — the shared predicate (replacing the inlined `REQUEST_ID`/`GOAL_ID`/`GOAL_STATUS` triple-check), evaluated only while the check is still armed. 3. `remove(id)` — taken (not cloned) only for a non-pattern message. This removes the `DataType` clone entirely, keeps the common consumed- check path at one lookup, and unifies the two previously drift-prone blocks (which the surrounding adora#172/#174 comments call out) behind a single method, so `recv()` and `StreamExt::next()` cannot diverge. This change is machine-generated by Claude (an AI assistant) as part of an automated code-review run, and reviewed against current origin/main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TMv79fayzGF9mDV7vPMQN7
Contributor
|
😎 Merged successfully - details. |
Collaborator
Author
|
🤖 Automated review by Claude — fully automated, no human in the loop. The shared Generated by Claude Code |
phil-opp
marked this pull request as ready for review
July 28, 2026 12:28
trunk-io
Bot
deleted the
claude/dreamy-bardeen-0efkxi-node-type-check-dedup
branch
July 28, 2026 14:40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
The first-message input type check ran on both receive paths (
recv_asyncandStream::poll_next) as two copy-pasted blocks, each doingself.input_type_checks.get(id).cloned()before deciding whether the message was pattern-correlated. For service/action inputs the check stays armed indefinitely (those inputs are polymorphic by pattern design), so the storedDataType— which can be a nestedStruct/List— was cloned and then discarded on every message on that input.The two blocks were also byte-for-byte duplicates (differing only in a log-message suffix), a drift risk the surrounding
adora#172/#174comments explicitly call out.Fix
Consolidate both paths into one
note_produced_eventhelper and order the guard so it is cheap in every case:input_type_checks.contains_key(id)— a single map lookup that short-circuits once the check has been consumed, preserving the existing "zero extra cost after the first message per input" property for steady-state topic traffic.carries_pattern_correlation(...)— the shared predicate (replacing the inlinedREQUEST_ID/GOAL_ID/GOAL_STATUStriple-check), evaluated only while the check is still armed.remove(id)— the value is taken, not cloned, and only for a non-pattern message.Net effect: the
DataTypeclone is removed entirely; the common consumed-check path stays at one lookup; and the two previously drift-prone blocks now share a single method, sorecv()andStreamExt::next()cannot diverge.Validation
cargo clippy -p dora-node-api --lib -- -D warningsclean (and--all-targets).cargo test -p dora-node-api --lib→ 147 passed.carries_pattern_correlation_*unit tests.origin/main. Please review carefully before merging.🤖 Generated with Claude Code
https://claude.ai/code/session_01TMv79fayzGF9mDV7vPMQN7
Generated by Claude Code