Fix/4085 ws json rpc batch - #4135
Open
Parikalp-Bhardwaj wants to merge 3 commits into
Open
Conversation
Parikalp-Bhardwaj
requested review from
DaniPopes,
grandizzy,
klkvr,
mattsse and
onbjerg
as code owners
August 12, 2026 12:26
Author
|
Hi @mattsse could you please review it? |
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.
Summary
Related #4085.
RpcClient::new_batch()correctly creates aRequestPacket::Batch, but the pubsub frontend was splitting that batch into individual requests before passing them to the transport.As a result, a batch containing multiple requests was sent as multiple WebSocket messages instead of a single JSON-RPC batch array.
This PR preserves the batch through the pubsub layer so WebSocket and IPC transports send it as one wire-level packet, while still tracking each request independently by JSON-RPC ID.
Problem
Previously,
PubSubFrontend::send_packet()handled a batch like this:Calling
self.send()for every request created a separatePubSubInstruction::Request, so the original batch was lost before reaching the backend.For a batch containing two requests, the flow was effectively:
With this change:
Changes
Preserve batches in the pubsub frontend
PubSubFrontend::send_packet()now creates anInFlightentry and response receiver for each request, but sends all of the requests to the service using a single batch instruction.Each request remains independently tracked, so response handling continues to use JSON-RPC IDs rather than array position.
Dispatch batches as one packet
The pubsub service now handles the batch as a single
RequestPacket::Batch.The existing
RequestPacketserialization is reused, so the batch is serialized as one JSON array and dispatched to the backend once.Each
InFlightrequest is still registered individually with theRequestManager.Handle batch responses
WebSocket and IPC previously expected each incoming message to deserialize into a single
PubSubItem.A new
PubSubItemshelper supports both:Batch response elements are forwarded individually to the existing frontend handling, where they are matched to pending requests by JSON-RPC ID.
This also means responses can arrive in a different order from the requests without affecting the corresponding futures.
IPC behavior
Because WebSocket and IPC share the pubsub frontend, IPC now preserves JSON-RPC batches on the wire as well.
Single-request behavior remains unchanged.
Reconnect behavior
Reconnect behavior is intentionally unchanged.
Pending requests are still reissued individually after reconnect. Preserving the original batch grouping across reconnects would introduce separate retry and idempotency concerns and is outside the scope of this fix.
This PR does not provide transactional batch semantics.
Empty batches
Existing empty-batch behavior is preserved.
returns an empty
ResponsePacket::Batchwithout sending anything to the backend.Tests
Added WebSocket regression tests covering:
new_batch()are sent as one WebSocket text frame containing a JSON arrayAdded JSON-RPC tests covering
PubSubItemsdeserialization for:The original #4085 behavior is also covered by the regression test: restoring the previous split behavior causes the WebSocket batch test to fail because the server receives individual JSON objects instead of one array.
Files changed
crates/json-rpc/src/notification.rs— addPubSubItemssupport for single items and arrayscrates/json-rpc/src/lib.rs— exportPubSubItemscrates/pubsub/src/ix.rs— add the internal batch instructioncrates/pubsub/src/frontend.rs— preserve batch grouping and individual response receiverscrates/pubsub/src/service.rs— serialize and dispatch batches once while tracking requests individuallycrates/transport-ws/src/lib.rs— handle incoming batch responsescrates/transport-ws/Cargo.toml— add the workspacealloy-json-rpcdependencycrates/transport-ipc/src/lib.rs— handle incomingPubSubItemscrates/rpc-client/tests/it/ws.rs— add WebSocket batch regression testscrates/rpc-client/Cargo.toml— add test dependencies required by the local WebSocket server