paritytech / jsonrpsee

Rust JSON-RPC library on top of async/await
MIT License
629 stars 169 forks source link

feat(types): serialize `id` in `Response` before `result`/`error` fields #1421

Closed ArtificialPB closed 2 months ago

ArtificialPB commented 2 months ago

Motivation

This change makes it possible to avoid buffering the result before being able to know how to decode it when using streaming response decoders.

For example, when using a WS connection, the client must track request ID's to know how to decode a response returned by the server. When using streaming-based JSON deserializers, you must buffer the result until you deserialize the ID of the response. This is wasteful for large / frequent messages.

Buffering example from a library we're developing: https://github.com/Kr1ptal/ethers-kt/blob/master/ethers-providers/src/main/kotlin/io/ethers/providers/WsClient.kt#L385-L394

Solution

Buffering can be avoided if the response serializes the ID before the result. The serialize function of Request type was updated to include the id field before result/error, see types/src/response.rs file changes. All other changes were made to update hardcoded test responses.

niklasad1 commented 2 months ago

Do you have any hunch of much of perf benefit this is or data (benchmarks)? The fix is trivial so looks good to me

ArtificialPB commented 2 months ago

@niklasad1 based on a quick profiling run, buffering in ethers-kt takes about 50% of the decoding time, and increases the amount of generated garbage by around the same ratio.

Decoding is still fast with buffering, but it's much better without :)

Screenshot 2024-07-04 at 19 39 26