feat(sdk): consume the request counter for partition operations - #3958
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #3958 +/- ##
=========================================
Coverage 84.92% 84.92%
+ Complexity 1405 1402 -3
=========================================
Files 1225 1225
Lines 179932 179943 +11
Branches 146219 146249 +30
=========================================
+ Hits 152812 152823 +11
+ Misses 23082 23063 -19
- Partials 4038 4057 +19
🚀 New features to boost your workflow:
|
|
Merge after #3945 |
hubcio
left a comment
There was a problem hiding this comment.
the id half looks right and lands uniformly in all five sdks. the checksum half doesn't belong in the same pr. inline comments cover what's inside the diff - the rest sits outside it:
core/server/src/dispatch.rs:1594-1604 - the partition path overwrites new_header.client with transport_client_id and clamps request to max(1). so the client half of a (client, request) dedup key is already discarded before the partition plane sees it, and transport_client_id changes on the very reconnect a retry follows. minting distinct ids buys a future dedup layer nothing until that rewrite changes too. the comment sitting right there - "a zero request id (the SDK does not number data-plane ops) is normalized" - is falsified by this pr and should be updated in it.
core/sdk/src/tcp/tcp_client.rs:1266 - the new hash runs inside the consensus_session std mutex. the comment at :121-124 picks std over tokio precisely because that section is "pure CPU"; it's now a full-batch hash blocking a tokio worker. quic_client.rs:630 is the same shape. hash the payload before taking the lock.
foreign/java/java-sdk/src/main/java/org/apache/iggy/client/async/tcp/vsr/ConsensusSession.java:56 - beginRegister() resets requestCounter to 1 but leaves correlationCounter alone. partition ops now draw from the counter that resets, so a re-login with an in-flight send can re-mint a RequestKey already in pendingRequests; registerRequest throws and writeVsrFrame turns that into closeChannel. that window used to be metadata-only.
core/simulator/src/client.rs:121-144 - still models the pre-pr client: partition ids from a separate counter at 1 << 63, metadata ids contiguous, checksum zero. the one tool that could find this interaction can't generate the pattern any more. its doc at :64 and :124-125 also still claims a gap-free requirement and a RequestGap, which client_table.rs:525 says does not exist.
stale doc sites: core/binary_protocol/src/consensus/header.rs:290 says the wire sends zero, client_table.rs:581 and :2825 repeat it, and node header.ts:116, go header.go:119, csharp VsrHeader.cs:24, java VsrHeaders.java:29 all state the server does not read the field. six places, all false. fix header.rs first since the others quote it.
foreign/go/internal/vsr/envelope_test.go:164 - the unbound-partition test checks only the error; its metadata twin at :156 also pins that the rejection burns no id. that invariant is live now that partition ops draw ids.
core/server/src/dispatch.rs:1015 - stamping makes the checksum-mismatch deny path reachable for SendMessages for the first time. it's terminal, no retry, and nothing tests it.
and nothing anywhere sends n batches then retries a metadata op to prove the gapped sequence still dedups end to end. worth one case in core/integration/tests/sdk/.
a045ec0 to
92c9ce8
Compare
|
/ready |
spetz
left a comment
There was a problem hiding this comment.
Some extra findings
Simulator
core/simulator/src/client.rs still models partition operations with a separate counter starting at 1 << 63, and its test asserts that partition operations do not consume the shared counter. Please update the simulator to use one counter for all replicated operations so it can generate the same sequence as the SDKs after this PR.
Server comment and dependency
core/server/src/dispatch.rs:1602 still says the SDK does not number data-plane operations, which becomes false after this PR. The compatibility normalization can remain, but the comment should distinguish current SDKs from older or internal callers. The stable VSR client-ID rewrite is handled by PR #3959, so that dependency should also be made explicit.
Go rejection invariant
foreign/go/internal/vsr/envelope_test.go verifies that an unbound metadata request does not consume an ID, but the equivalent partition test only checks the error. Since partition operations now consume the same counter, please also assert that CurrentRequestID() remains 1 after the rejection.
Existing checksum documentation
Several comments still claim request checksums are always zero or are not read by the server, including header.rs, client_table.rs, and the Go, Node, C#, and Java header mirrors. That was already stale before this final diff, so it does not need to block this PR, but it should be cleaned up separately.
aa4c203 to
13c671c
Compare
|
/ready |
|
LGTM after deep review. |
Our partition operations did not use the
requestcounter which meant that partition ops did not participate in the deduplication process. This PR makes the partition operations bump the request counter for all of the SDKs