rpc
An async ONC-RPC (RFC 5531) client and server API for Rust.
| Crate | Purpose |
|---|---|
thruput-rpc-api |
Stable traits and types for generated bindings |
thruput-rpc-driver |
Transports, pools, server, dispatch; re-exports thruput-rpc-api |
rpc-api-fixture |
Proves generated bindings need only thruput-rpc-api |
thruput-rpc-api versions independently: keep changes additive (patch bump); a
breaking change forces every generated protocol crate to republish. It has no
thruput-xdrs dependency. thruput-rpc-driver is versioned and released with
thruput-xdrs.
Features
- Async TCP client and server with program/version dispatch
- Ready handlers reply inline; only suspended handlers spawn tasks
- Bidirectional RPC: handlers can call back to the peer via
peer() - Pools:
MultiplexPool,FixedSerialPool,DynamicPool,CpuSetPool - Handler panics return
SYSTEM_ERRwithout closing the connection tracingspans for logging and OpenTelemetry- 16 MiB default message-size limit; TCP keepalive (60 s idle)
Callers own request deadlines; keepalive does not bound RPC latency.
Usage
use ;
use TcpListener;
// Server
let mut services = new;
services.add_service;
let listener = bind.await?;
let _handle = new.start.await;
// Client
let conn = connect_client.await?;
let response = conn.send_call.await?;
Connection limits
let config = new
.with_output_admission_threshold_bytes
.with_max_suspended_handlers;
- Output admission threshold (bytes of queued output): an outgoing call
that would exceed it fails locally with
SystemError; once the backlog is at or above it, incoming calls getSYSTEM_ERR. Replies always go through. Not a hard memory bound. - Max suspended handlers: excess suspended handlers are dropped with
SYSTEM_ERR; ready handlers still complete.
Both default to None (unlimited).
Testing without TCP
thruput_rpc_driver::loopback::LoopbackLink connects two ServiceMaps in-process
for unit tests of code that holds an Arc<dyn RpcSender>:
use LoopbackLink;
let link = connect
.with_latency; // one-way, tokio time
let = link.senders;
let client = new;
link.poison; // in-flight and later calls fail with SystemError
Latency uses tokio time, so start_paused = true tests run instantly.
Message-size limits, admission, and pools are not modeled.
Tracing
Spans: rpc_connection{peer, role} (INFO) → rpc_call{xid, prog, vers, proc}
(DEBUG). Use FmtSpan::CLOSE with tracing-subscriber to log durations, or
tracing-opentelemetry for export.
Known issues
- Multi-part (fragmented) records cause connection shutdown.
License
See LICENSE.