Reduce app-server JSON serialization overhead (#34761)

## What changed

- Decode `JSONRPCRequest` into `ClientRequest` without serializing the entire request back into an intermediate JSON value.
- Define every client method's wire name explicitly and use it directly for request, response, and tracing method lookups.
- Serialize outgoing transport messages directly to JSON strings instead of first building a `serde_json::Value`.

## Testing

- Add regression coverage that compares direct request conversion with Serde decoding, including omitted and null parameters, legacy methods, and unknown methods.
- Verify that direct outgoing-message serialization preserves the notification wire shape.

GitOrigin-RevId: 304e14bcaea24e32743bf852a60a208e2f273db3
This commit is contained in:
jif authored and copyberry committed 2026-07-22 14:16:51 +00:00
1 parent 65ae4c26e0
commit f69dc49b15
4 files changed
+148 -47

No files matched your search

@@ -256,14 +256,7 @@ async fn enqueue_incoming_message(
}
fn serialize_outgoing_message(outgoing_message: OutgoingMessage) -> Option<String> {
let value = match serde_json::to_value(outgoing_message) {
Ok(value) => value,
Err(err) => {
error!("Failed to convert OutgoingMessage to JSON value: {err}");
return None;
}
};
match serde_json::to_string(&value) {
match serde_json::to_string(&outgoing_message) {
Ok(json) => Some(json),
Err(err) => {
error!("Failed to serialize JSONRPCMessage: {err}");
@@ -295,6 +288,32 @@ mod tests {
);
}
#[test]
fn serialize_outgoing_message_preserves_wire_shape() {
let message = OutgoingMessage::AppServerNotification(ServerNotificationEnvelope {
notification: ServerNotification::ConfigWarning(ConfigWarningNotification {
summary: "summary".to_string(),
details: None,
path: None,
range: None,
}),
emitted_at_ms: Some(1_234),
});
let json = serialize_outgoing_message(message).expect("message should serialize");
assert_eq!(
serde_json::from_str::<serde_json::Value>(&json).expect("message should be valid JSON"),
json!({
"method": "configWarning",
"params": {
"summary": "summary",
"details": null,
},
"emittedAtMs": 1_234,
})
);
}
#[tokio::test]
async fn enqueue_incoming_request_returns_overload_error_when_queue_is_full() {
let connection_id = ConnectionId(42);