-
Notifications
You must be signed in to change notification settings - Fork 30
clients: reduce mem usage, refactor protocol handling #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
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
JSON-RPC is modelled as request-response where each response corresponds to one request, sent in the same order. In addition, batching is possible where several requests can be sent as one batch, receiving one batch of responses in return, but still maintaining the general 1:1 messaging structure. This PR exploits this 1:1 relationship between request and response to simplify the client implementation and improve efficieny (reduces mem usage from 1.2gb to 800mb to send a 128mb message - still a lot, but quite a bit better) while at the same time cleaning up error handling and moving the JSON-RPC specifics out of the transports so that they're equal and shared between each transport. The transports themselves now just provide the simple ability to transfer request-response pairs. In doing so, protocol adherence in edge cases is increased to more closely follow the semantics suggested in the spec. * match messages by order, getting rid of unnecessary matching table * move all JSON-RPC protocol implementation details such as encoding/decoding etc to `clients`, avoiding it being spread out and repeated in each transport - this also opens the door to using a different encoding than JSON in the future (ie CBOR) * stream-encode requests and use `seq[byte]` throughout to avoid costly `string` conversions / copies * clean up error raising - in particular, differentiate between transport and protocol errors more clearly and strive to raise similar exceptions in similar situations for each transport * add `maxMessageSize` parameter to each transport, make it work the same * remove socket client reconnect loop to match websockets - possibly it should be re-added to both instead in a future PR * add `raises` to `async`, where relevant * order request/response json fields the way they're ordered in the spec * this makes it more efficient to parse messages following the same order * make parser more spec-compliant, moving some of the validation to an earlier stage in the parsing pipeline * limit the length of string-based `id` fields to avoid having the log spammed * stream-write requests, avoiding an extra copy of the parameters * use raw async procs where applicable to avoid copies and async overhead
arnetheduck
added a commit
that referenced
this pull request
Nov 24, 2025
The message processing hook is intended for handling notifications /
requests from the server which can happen with for example websockets
and other bidirectional transports.
When using the HTTP endpoint, the server does not really have the
opportunity to send anything except the response since the connection is
unidirectional.
* don't call processing hook for http endpoint
* make raised exceptions more accurate with respect to spec
* `InvalidRequest` -> `ApplicationError`, deprecate former name
* one less copy of parameters in rpc macro code
* more strict handling of missing / null fields in jrpc_sys
* differentiate between `null` and "not present" id in requests
* allow `null` request id ("not present"/notifications TODO!)
* don't allow `null` parameter list - allow a non-present one
* stop parsing earlier when `jsonrpc` tag is missing/wrong
* restore some backwards compat with web3, broken in #247
* discard empty batches earlier
arnetheduck
added a commit
that referenced
this pull request
Nov 28, 2025
The message processing hook is intended for handling notifications /
requests from the server which can happen with for example websockets
and other bidirectional transports.
When using the HTTP endpoint, the server does not really have the
opportunity to send anything except the response since the connection is
unidirectional.
* don't call processing hook for http endpoint
* make raised exceptions more accurate with respect to spec
* `InvalidRequest` -> `ApplicationError`, deprecate former name
* one less copy of parameters in rpc macro code
* more strict handling of missing / null fields in jrpc_sys
* differentiate between `null` and "not present" id in requests
* allow `null` request id ("not present"/notifications TODO!)
* don't allow `null` parameter list - allow a non-present one
* stop parsing earlier when `jsonrpc` tag is missing/wrong
* restore some backwards compat with web3, broken in #247
* discard empty batches earlier
* fix cancellation on close with released webscok
* remove unused `RequestBatchTx`/`ResponseBatchTx`
* streamline jrpc_sys tests
* add workaround for nim-lang/Nim#24844
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.
JSON-RPC is modelled as request-response where each response corresponds to one request, sent in the same order. In addition, batching is possible where several requests can be sent as one batch, receiving one batch of responses in return, but still maintaining the general 1:1 messaging structure.
This PR exploits this 1:1 relationship between request and response to simplify the client implementation and improve efficieny (reduces mem usage from 1.2gb to 800mb to send a 128mb message - still a lot, but quite a bit better) while at the same time cleaning up error handling and moving the JSON-RPC specifics out of the transports so that they're equal and shared between each transport.
The transports themselves now just provide the simple ability to transfer request-response pairs.
In doing so, protocol adherence in edge cases is increased to more closely follow the semantics suggested in the spec.
clients, avoiding it being spread out and repeated in each transport - this also opens the door to using a different encoding than JSON in the future (ie CBOR)seq[byte]throughout to avoid costlystringconversions / copiesmaxMessageSizeparameter to each transport, make it work the sameraisestoasync, where relevantidfields to avoid having the log spammed