pub struct Builder { /* private fields */ }Expand description
Builds an unbound client or server endpoint.
A builder advertises one application-protocol name and supported versions.
Its terminal client* or server* method consumes it, performs the
handshake, and returns an unbound endpoint that can be inspected before
binding it to a concrete Protocol. Limit setters override defaults;
size and concurrency limits are negotiated to the more conservative value,
while copy thresholds are local performance settings.
Implementations§
Source§impl Builder
impl Builder
Sourcepub fn new(name: &str, versions: &[u16]) -> Self
pub fn new(name: &str, versions: &[u16]) -> Self
Starts a builder for an application-protocol name and supported versions.
versions must be nonempty and unique.
Sourcepub fn key(self, key: AuthKey) -> Self
pub fn key(self, key: AuthKey) -> Self
Requires mutual proof of a pre-shared key during negotiation.
Both endpoints must be configured with the same key, or neither: a
mismatch in either direction aborts the handshake. See crate::auth
for what this does and does not protect against.
Sourcepub fn max_fragment_size(self, value: usize) -> Self
pub fn max_fragment_size(self, value: usize) -> Self
Sets the maximum complete wire-fragment size, including its header.
This bounds one round-robin write of a fragmented message. Defaults to 512 KiB; the peer and local endpoint use the smaller advertised value.
Sourcepub fn max_payload_size(self, value: usize) -> Self
pub fn max_payload_size(self, value: usize) -> Self
Sets the maximum reassembled postcard payload, excluding a trailer.
Defaults to 2 MiB; the peer and local endpoint use the smaller
advertised value, and it is lowered further to the negotiated
max_outstanding_payload if that
ends up smaller — a per-message cap above the aggregate pool would
describe a message that could never be sent.
Sourcepub fn max_outstanding_payload(self, value: usize) -> Self
pub fn max_outstanding_payload(self, value: usize) -> Self
Sets the session-wide postcard payload quota, in bytes.
This bounds the total charged payload bytes of every call that has not
yet released, across the whole connection. Unlike
max_payload_size, which bounds one message,
this bounds the sum — and it is charged for the entire call
lifecycle, from the sender admitting the message to the receiving
application being done with it, not merely while the payload is being
reassembled. A payload’s memory does not end at dispatch.
The consequence is a contract worth knowing: a long-pending call with a
large payload holds its share of the pool for as long as it pends, and
throttles the connection accordingly. Indefinitely pending calls are
legitimate — an event poll is the usual shape — and a large payload on
one is unusual but not unthinkable. If you want both, release
explicitly (see
CallContext::release_payload
and CallResult::take_payload_credit)
once you no longer need the request. Violating it degrades throughput;
it does not hang anything.
Trailer bytes are counted against
trailer_session_window instead, and
the two pools are deliberately separate: a handler that must consume a
trailer before it can release its payload would deadlock against a
shared one.
The pool measures wire bytes, and a struct-heavy payload can occupy
several times that once deserialized. Defaults to 16 MiB; the peer and
local endpoint use the smaller advertised value, raised to at least
this endpoint’s own max_payload_size before it is advertised.
Sourcepub fn trailer_credit_interval(self, value: usize) -> Self
pub fn trailer_credit_interval(self, value: usize) -> Self
Sets how much retired trailer credit accumulates before it is returned to the peer, in bytes.
Purely a local coalescing knob: it is not negotiated, the two ends
need not agree on it, and it bounds nothing — what bounds the peer is
trailer_session_window. Larger
values mean fewer credit fragments and a coarser feedback signal.
Credit is flushed regardless once the pool is exhausted or a trailer
ends, so no value can stall a sender.
Defaults to 256 KiB.
Sourcepub fn trailer_session_window(self, value: usize) -> Self
pub fn trailer_session_window(self, value: usize) -> Self
Sets the session-wide trailer credit pool, in bytes.
This bounds trailer data the peer has sent but this end has not yet retired — released by the consuming application, which is later than merely reading it — across all trailers at once. It is the only credit limit and the whole bound on receiver memory attributable to trailers, however many are open. There is no separate cap on a trailer’s total size, so a trailer may stream indefinitely.
There is deliberately no per-trailer subdivision: a sender that lets one trailer consume the pool starves only its own other trailers, so dividing it up is the sending end’s local scheduling choice rather than a protocol rule — and any division it chooses is safe, since credit is flushed whenever a consumer is left waiting and not merely at the coalescing threshold. The corollary is that a consumer which stalls indefinitely can hold as much of the pool as the peer chose to spend on it.
Defaults to 16 MiB; the peer and local endpoint use the smaller
advertised value, floored at 1. A value below
max_fragment_size is legal but merely
produces short fragments.
Sourcepub fn max_handles_per_fragment(self, value: usize) -> Self
pub fn max_handles_per_fragment(self, value: usize) -> Self
Sets the maximum native handles carried by one wire fragment.
Defaults to 8, is capped to the transport’s operating-system limit, and is negotiated down to the peer’s advertised value.
Sourcepub fn max_handles_per_message(self, value: usize) -> Self
pub fn max_handles_per_message(self, value: usize) -> Self
Sets the maximum native handles carried by one message.
Defaults to 8; the peer and local endpoint use the smaller advertised value.
Sourcepub fn trailer_recv_copy_threshold(self, value: usize) -> Self
pub fn trailer_recv_copy_threshold(self, value: usize) -> Self
Sets the receive-side eager-copy threshold for an undemanded fragment.
A fragment at or below this size is copied immediately, allowing the connection receive loop to continue without waiting for the trailer reader. Defaults to 64 KiB. Set zero to disable nonempty eager copies.
Sourcepub fn trailer_recv_demand_copy_threshold(self, value: usize) -> Self
pub fn trailer_recv_demand_copy_threshold(self, value: usize) -> Self
Sets the receive-side eager-copy threshold for a demanded fragment.
This applies when the trailer reader is already waiting for the next fragment. Defaults to 256 KiB. Set zero to disable nonempty eager copies on this path.
Sourcepub fn trailer_send_copy_threshold(self, value: usize) -> Self
pub fn trailer_send_copy_threshold(self, value: usize) -> Self
Sets the send-side staging threshold for a trailer fragment.
A write at or below this size is copied into staging without waiting for a transport grant. Defaults to 64 KiB. Set zero to disable nonempty eager staging.
Sourcepub fn max_concurrent_calls(self, value: usize) -> Self
pub fn max_concurrent_calls(self, value: usize) -> Self
Sets the maximum number of concurrent calls, counted from a request’s first fragment to its response.
Requests still being reassembled count against it alongside those
already dispatched, so the two together can never exceed this.
Messages that have entered their trailer phase are excluded — a
trailer may outlive its call, and is bounded by
trailer_session_window instead.
This is a count and not a memory bound; what bounds the memory those
calls hold is
max_outstanding_payload, which is
why the default is generous.
Defaults to 1024; the peer and local endpoint use the smaller advertised value.
Sourcepub async fn client<T>(self, stream: T) -> Result<Unbound, Error>
pub async fn client<T>(self, stream: T) -> Result<Unbound, Error>
Negotiates a client session over a bidirectional byte stream.
Sourcepub async fn client_split<R, W>(
self,
reader: R,
writer: W,
) -> Result<Unbound, Error>
pub async fn client_split<R, W>( self, reader: R, writer: W, ) -> Result<Unbound, Error>
Negotiates a client session over separate byte-stream reader and writer halves.
Sourcepub async fn client_unix(self, stream: UnixStream) -> Result<Unbound, Error>
Available on Unix only.
pub async fn client_unix(self, stream: UnixStream) -> Result<Unbound, Error>
Sourcepub async unsafe fn client_named_pipe_server(
self,
pipe: NamedPipeServer,
peer_process: OwnedHandle,
) -> Result<Unbound, Error>
Available on Windows only.
pub async unsafe fn client_named_pipe_server( self, pipe: NamedPipeServer, peer_process: OwnedHandle, ) -> Result<Unbound, Error>
Starts a client session on the server end of a Windows named pipe.
peer_process is retained for the lifetime of the session and must
grant process-query and synchronization access. Construction fails if
it does not identify the named-pipe peer.
§Safety
The identified peer must be trusted to send only handle values that it
created in this process with DuplicateHandle. A malicious peer can
otherwise cause this process to close arbitrary handles.
Sourcepub async unsafe fn client_named_pipe_client(
self,
pipe: NamedPipeClient,
peer_process: OwnedHandle,
) -> Result<Unbound, Error>
Available on Windows only.
pub async unsafe fn client_named_pipe_client( self, pipe: NamedPipeClient, peer_process: OwnedHandle, ) -> Result<Unbound, Error>
Starts a client session on the client end of a Windows named pipe.
peer_process is retained for the lifetime of the session and must
grant process-query and synchronization access. Construction fails if
it does not identify the named-pipe peer.
§Safety
The identified peer must be trusted to send only handle values that it
created in this process with DuplicateHandle. A malicious peer can
otherwise cause this process to close arbitrary handles.
Sourcepub async fn server<T>(self, stream: T) -> Result<Unbound, Error>
pub async fn server<T>(self, stream: T) -> Result<Unbound, Error>
Negotiates a server session over a bidirectional byte stream.
Sourcepub async fn server_split<R, W>(
self,
reader: R,
writer: W,
) -> Result<Unbound, Error>
pub async fn server_split<R, W>( self, reader: R, writer: W, ) -> Result<Unbound, Error>
Negotiates a server session over separate byte-stream reader and writer halves.
Sourcepub async fn server_unix(self, stream: UnixStream) -> Result<Unbound, Error>
Available on Unix only.
pub async fn server_unix(self, stream: UnixStream) -> Result<Unbound, Error>
Sourcepub async fn server_named_pipe_server(
self,
pipe: NamedPipeServer,
) -> Result<Unbound, Error>
Available on Windows only.
pub async fn server_named_pipe_server( self, pipe: NamedPipeServer, ) -> Result<Unbound, Error>
Creates a server on the server end of a Windows named pipe.
Sourcepub async fn server_named_pipe_client(
self,
pipe: NamedPipeClient,
) -> Result<Unbound, Error>
Available on Windows only.
pub async fn server_named_pipe_client( self, pipe: NamedPipeClient, ) -> Result<Unbound, Error>
Creates a server on the client end of a Windows named pipe.