Optimize /solve request serialization in autopilot#4159
Optimize /solve request serialization in autopilot#4159MartinquaXD wants to merge 2 commits intomainfrom
/solve request serialization in autopilot#4159Conversation
There was a problem hiding this comment.
Code Review
This pull request optimizes /solve request serialization by using Bytes to avoid repeated allocations and copies, and moves serialization to a blocking task. This is a good performance improvement. I have found one high-severity issue related to potential panics and inefficiencies in tracing/logging code that could affect service stability and performance.
| fn body_to_string(&self) -> Cow<'_, str> { | ||
| let serialized = serde_json::to_string(&self).unwrap(); | ||
| Cow::Owned(serialized) | ||
| } |
There was a problem hiding this comment.
Using .unwrap() on the result of serde_json::to_string can cause a panic if serialization fails. In a tracing context, this can crash the service, creating a potential denial-of-service vulnerability. It is safer to handle this error gracefully, as shown in the suggestion. Furthermore, serializing data to JSON and then immediately parsing it back into a serde_json::Value within the same operation is inefficient. For tracing, consider using a tracing::field::Visit implementation to directly collect fields into a serde_json::Map to avoid unnecessary serialization/deserialization cycles, which is a more robust and efficient approach for this context.
fn body_to_string(&self) -> Cow<'_, str> {
match serde_json::to_string(self) {
Ok(serialized) => Cow::Owned(serialized),
Err(_) => Cow::Borrowed("<failed to serialize body>"),
}
}References
- Avoid serializing data to JSON and then immediately parsing it back into a
serde_json::Valuewithin the same operation, as this is inefficient and can impact performance. Instead, consider using atracing::field::Visitimplementation to directly collect fields into aserde_json::Mapto avoid unnecessary serialization/deserialization cycles.
Description
Currently the way the autopilot serializes
/solverequests is still sub optimal. While it does indeed only serialize the/solverequests once it still allocates memory for every HTTP request it ultimately sends.Since
reqwestalso supportsBytesas the request body which are already references counted we can save a bunch of allocating and copying data by serializing the auction data into aBytesinstance and cloning that into the individual/solveHTTP requests.Changes
solve::Requestfromserde_json::RawValuetoBytesX-Auction-Idheader which is important for another optimization but that has to be merged before said optimizationHow to test
existing e2e tests