Expand description
§rpc_api
Stable API boundary for the Thruput ONC-RPC stack.
This crate owns the shared public types that connect three parties:
rpc_driver— the transport, pool, and dispatch implementation. It depends on this crate, re-exports everything here at its historical paths, and implementsRpcSenderfor its connections and pools.- Generated protocol bindings (protocol-rs clients and dispatchers), which are generated against this crate only and acquire no transport dependency.
- Consumers, which wire generated clients and dispatchers to driver connections.
Because all three share these types through a single, rarely-changing
crate, rpc_driver can make breaking implementation-only releases
(pools, configuration, transports) without forcing generated protocol
crates to republish.
§Stability
This crate is intentionally tiny, and its dependencies are limited to
async-trait and thiserror. XDR serialization is the generated
bindings’ business: they encode through CallBuf::append_with with
the xdrs they were generated against, so an xdrs release never
forces a release here. Changes must be additive wherever
possible: new RpcError variants are non-breaking thanks to
#[non_exhaustive], and a new trait method ships with a default
implementation when a correct one exists for every sender. A breaking
change here forces a coordinated republish of every generated protocol
crate — treat it as a last resort.
§Sending a call
Callers take a CallBuf from the sender with RpcSender::call_buf,
encode the arguments into it, and pass it to RpcSender::send_call.
The buffer keeps the wire prefix reserved ahead of the payload so the
driver frames the call in place, and driver senders recycle spent record
buffers through call_buf, so a steady stream of calls allocates
nothing. CallBuf::append_with hands the record buffer to a closure
that serializes into it in place; generated protocol clients encode
their argument tuple that way.
use rpc_api::CallBuf;
let mut call = CallBuf::new();
call.extend_from_slice(&42u32.to_be_bytes());
assert_eq!(call.payload(), &[0, 0, 0, 42]);§Chunked messages
A message too large for one record goes out as a run of records that
may arrive in any order. ChunkPosition says where a record sits in
its run, and a protocol crate implements ChunkRecord for each of its
chunked records; rpc_driver::ChunkRunAssembler reassembles the runs on
the server, so handlers push the records they receive as they are.
Structs§
- CallBuf
- Payload of an outgoing RPC call, with room reserved ahead of it for the record mark and call header the driver writes when it sends the call.
- Chunk
Position - Where one record sits in the run of records that together carry a
message too large for one RPC record: its index, from 0, and the run’s
length. Every record of a run carries the same
count, each index in[0, count)is sent exactly once, and a run always has at least one record, so an empty message is a run of one empty record. The sender may issue a run’s calls concurrently and over several connections, so its records can arrive in any order, and the runs of several messages can be in flight at once; the driver’sChunkRunAssemblerputs them back together. - Prog
Vers - RPC program and version identifier.
- Program
Error - Generic error type for RPC program implementations.
- RpcResponse
- Response from an RPC call. Wraps the raw record buffer and payload
offset, providing zero-copy access to the payload via
Deref<Target = [u8]>.
Enums§
- RpcError
- Errors that can occur while preparing or performing RPC calls.
Traits§
- Chunk
Record - A wire record that is one chunk of a run: it names the message it is part of (its key, such as a batch number), its position in the run, and carries its part of the message’s items.
- RpcHandler
- Trait for implementing RPC service handlers.
- RpcSender
- Trait for making outgoing RPC calls.