-
Notifications
You must be signed in to change notification settings - Fork 273
Request<T> and Response<T> for faster serialization #212
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
Comments
Yup, make perfect sense. Probably can be even done with backward compatibility by doing |
A possible set of problems are things like It basically works because tuples are serialized with |
Previously, all responses were converted to serde_json::Value before being serialized to string. Since jsonrpc does not inspect the result object in any way, this step could be skipped. Now, result objects are serialized to string much earlier and the Value step is skipped. This patch has large performance benefits for huge responses: In tests with 4.5 GB responses, the jsonrpc serialization overhead after returning from an rpc function was reduced by around 35%. Which means several seconds of speed-up in response times. To accomplish this while mostly retaining API compatibility, the traits RpcMethod, RpcMethodSync, RpcMethodSimple are now generic in their return type and are wrapped when added to an io handler. There's now a distinction between the parsed representation of jsonrpc responses (Output/Response) and result of rpc functions calls (WrapOutput/WrapResponse) to allow the latter to carry the pre-serialized strings. Review notes: - I'm not happy with the WrapOutput / WrapResponse names, glad for suggestions. - Similarly, rpc_wrap must be renamed and moved. - The http handler health request is now awkward, and must extract the result/error from the already-serialized response. Probably worth it. - The largest API breakage I could see is in the middleware, where the futures now return WrapOutput/WrapResult instead of Output/Result. - One could make WrapOutput just be String, but having a separate type is likely easier to read. See paritytech#212
Previously, all responses were converted to serde_json::Value before being serialized to string. Since jsonrpc does not inspect the result object in any way, this step could be skipped. Now, result objects are serialized to string much earlier and the Value step is skipped. This patch has large performance benefits for huge responses: In tests with 4.5 GB responses, the jsonrpc serialization overhead after returning from an rpc function was reduced by around 35%. Which means several seconds of speed-up in response times. To accomplish this while mostly retaining API compatibility, the traits RpcMethod, RpcMethodSync, RpcMethodSimple are now generic in their return type and are wrapped when added to an io handler. There's now a distinction between the parsed representation of jsonrpc responses (Output/Response) and result of rpc functions calls (WrapOutput/WrapResponse) to allow the latter to carry the pre-serialized strings. Review notes: - I'm not happy with the WrapOutput / WrapResponse names, glad for suggestions. - Similarly, rpc_wrap must be renamed and moved. - The http handler health request is now awkward, and must extract the result/error from the already-serialized response. Probably worth it. - The largest API breakage I could see is in the middleware, where the futures now return WrapOutput/WrapResult instead of Output/Result. - One could make WrapOutput just be String, but having a separate type is likely easier to read. See paritytech#212
Previously, all responses were converted to serde_json::Value before being serialized to string. Since jsonrpc does not inspect the result object in any way, this step could be skipped. Now, result objects are serialized to string much earlier and the Value step is skipped. This patch has large performance benefits for huge responses: In tests with 4.5 GB responses, the jsonrpc serialization overhead after returning from an rpc function was reduced by around 35%. Which means several seconds of speed-up in response times. To accomplish this while mostly retaining API compatibility, the traits RpcMethod, RpcMethodSync, RpcMethodSimple are now generic in their return type and are wrapped when added to an io handler. There's now a distinction between the parsed representation of jsonrpc responses (Output/Response) and result of rpc functions calls (WrapOutput/WrapResponse) to allow the latter to carry the pre-serialized strings. Review notes: - I'm not happy with the WrapOutput / WrapResponse names, glad for suggestions. - Similarly, rpc_wrap must be renamed and moved. - The http handler health request is now awkward, and must extract the result/error from the already-serialized response. Probably worth it. - The largest API breakage I could see is in the middleware, where the futures now return WrapOutput/WrapResult instead of Output/Result. - One could make WrapOutput just be String, but having a separate type is likely easier to read. See paritytech#212
The current
Request
andResponse
objects ultimately hold on toserde_json::Value
for their actual values. This forces a user of those objects to first serialize/deserialize their typesT
to/from aserde_json::Value
between the wire representation and the finalT
representation. I have not done any performance benchmarks, but I guess serializing twice does cost quite a lot of extra resources.If these types had a generic it would be possible to have them deserialize directly from a wire format to their target type
T
. There would of course be some obstacles to overcome to make this work, but I think it could work. What do you think?The text was updated successfully, but these errors were encountered: