feat: rpc response message chunking #3336
Merged
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.
Description
Adds server-side "chunking" protocol for large RPC responses.
Given a payload exceeding some threshold, comms RPC will split message payloads into a number (maximum 16)
RPC messages and stream them to the client. The client will recombine the message payloads before emitting it to
the caller.
BREAKING CHANGE: Backward compatible (client-side), an upgraded node may request from an older node and process
responses. Since an older node cannot process chunks, if a response contains any, the response will be invalid to the older node. Otherwise, if less than the payload threshold, the response is exactly as before.
Motivation and Context
Large streamed message payloads (those seen in block sync) are often ~ 1.2 MiB over the wire.
The Bandwidth Delay product is often low/very low for connections over tor resulting in large message frames will take many seconds to be completely received.
This PR breaks message payloads into smaller chunks with less time between receiving a full frame on the client side.
The algorithm for chunking is as follows:
a.
payload <= THRESHOLD
: emit a single frameb.
payload > THRESHOLD && payload <= SIZE_LIMIT
: emit a single frame containing the full payloadc.
payload > SIZE_LIMIT
: emit a one or more frames containing the nextSIZE_THRESHOLD
bytes, with the final frame either as per (a) or (b).This is done to prevent an unnecessary/very small trailing chunk when a payload is only a handful of bytes over the threshold
e.g 256Kb (
THRESHOLD
) + 1 byte results in one chunk not two. 384Kb (SIZE_LIMIT
) + 1 kb resultsin 2 frames of 256Kb and 129Kb respectively. meaning each chunk has a maximum size of
SIZE_LIMIT
and thetrailing/last chunk has a minimum size of
SIZE_LIMIT - THRESHOLD (128kb)
How Has This Been Tested?
Some new unit tests, existing large message tests, manual archival sync using force sync