RPC

Request-response calls between agents with 30-second timeout.

Making a call#

use subway_proto::rpc::{RpcRequest, RpcResponse};
 
let response = node.call("worker.relay", RpcRequest {
    correlation_id: uuid::Uuid::new_v4().to_string(),
    method: "process".into(),
    payload: b"input data".to_vec(),
    metadata: Default::default(),
}).await?;
 
if response.success {
    println!("result: {}", String::from_utf8_lossy(&response.payload));
} else {
    println!("error: {}", response.error);
}

call() blocks until the response arrives or the 30-second timeout expires.

Handling RPC requests#

Synchronous handler

node.handle_rpc(|req: RpcRequest| -> RpcResponse {
    RpcResponse {
        correlation_id: req.correlation_id,
        success: true,
        payload: format!("echo: {}", String::from_utf8_lossy(&req.payload)).into_bytes(),
        error: String::new(),
    }
});

Async handler

node.handle_rpc_async(|req: RpcRequest| async move {
    let result = do_expensive_work(&req.payload).await;
    RpcResponse {
        correlation_id: req.correlation_id,
        success: true,
        payload: result,
        error: String::new(),
    }
});

handle_rpc_async spawns a new tokio task per request — long-running handlers won't block other RPCs.

Call by PeerId#

Skip name resolution if you already have the PeerId:

let peer_id = node.resolve("worker.relay").await?;
let response = node.call_by_peer_id(peer_id, request).await?;

RPC message format#

RpcRequest:

FieldTypeDescription
correlation_idstringLinks request to response
methodstringRPC method name
payloadbytesRequest body
metadatamap<string, string>Key-value metadata

RpcResponse:

FieldTypeDescription
correlation_idstringMatches the request
successboolWhether the call succeeded
payloadbytesResponse body
errorstringError message (empty on success)

Timeout#

RPC calls timeout after 30 seconds by default. A SubwayError::Timeout is returned.

Warning

If your handler takes longer than 30s, the caller gets a timeout error even if the handler eventually completes. Design handlers to be fast or use handle_rpc_async with its own timeout logic.