pub struct ReliableStream { /* private fields */ }Expand description
Reliable stream mode with selective NACKs.
Features:
- Bounded retransmit window (32 packets)
- Selective NACKs (receiver-driven)
- Per-stream state
- Configurable RTO
Suitable for:
- Tool call results
- Guardrail decisions
- Session lifecycle events
- Error propagation
Implementations§
Source§impl ReliableStream
impl ReliableStream
Sourcepub const DEFAULT_RTO: Duration
pub const DEFAULT_RTO: Duration
Default retransmit timeout — the starting RTO before any RTT sample, and the value used by fixed-RTO callers.
Sourcepub const MIN_RTO: Duration
pub const MIN_RTO: Duration
Lower bound on the adaptive RTO (H-5). Floors the estimate so a near-zero localhost RTT can’t drive the RTO below the grant-drain
- processing latency and cause spurious resends.
Sourcepub const MAX_RTO: Duration
pub const MAX_RTO: Duration
Upper bound on the adaptive RTO (H-5). Caps how long a genuinely lost packet waits before the timeout backstop resends it.
Sourcepub const DEFAULT_MAX_PENDING: usize = 32
pub const DEFAULT_MAX_PENDING: usize = 32
Default max pending packets — also the floor when the window is
auto-sized from a stream’s tx-window (see
Self::max_pending_for_window).
Sourcepub const MIN_TRACKED_PACKET_BYTES: u32 = 512
pub const MIN_TRACKED_PACKET_BYTES: u32 = 512
Lower bound on the per-packet size assumed when sizing the
retransmit window from a tx-window. The window must track at least
tx_window / MIN_TRACKED_PACKET_BYTES packets so nothing in flight
is evicted before it can be retransmitted. 512 B covers bulk (MTU)
and typical control packets; sub-512 B spam on a huge window is the
only residual eviction risk — surfaced loudly via
Self::untracked_evictions (H-2).
Sourcepub const MAX_RETRANSMIT_WINDOW: usize = 16_384
pub const MAX_RETRANSMIT_WINDOW: usize = 16_384
Hard cap on the auto-sized retransmit window, bounding the pending queue’s worst-case growth under sustained loss.
Sourcepub const DEFAULT_MAX_RETRIES: u8 = 3
pub const DEFAULT_MAX_RETRIES: u8 = 3
Default max retries
Sourcepub const INIT_CWND: f64 = 32.0
pub const INIT_CWND: f64 = 32.0
Initial congestion window in packets (H-6). ~TCP initial window; big enough that low-volume reliable streams (nRPC) never feel it.
Sourcepub const MIN_CWND: f64 = 2.0
pub const MIN_CWND: f64 = 2.0
Congestion-window floor — a stream under sustained loss still makes forward progress at this many packets in flight.
Sourcepub fn max_pending_for_window(tx_window: u32) -> usize
pub fn max_pending_for_window(tx_window: u32) -> usize
Size the retransmit window to a stream’s tx-credit window so the
sender can never have more packets in flight than it can
retransmit (the H-1 invariant: tx-window ≤ retransmit-window).
tx_window == 0 (backpressure disabled) falls back to the default.
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new reliable stream with default settings.
pending is NOT pre-reserved: it grows on demand to the actual
in-flight count (itself bounded by the tx-window’s bytes), so a
generous max_pending costs nothing up front — important when
thousands of small-payload streams each carry a reliability state.
Sourcepub fn with_settings(rto: Duration, max_pending: usize, max_retries: u8) -> Self
pub fn with_settings(rto: Duration, max_pending: usize, max_retries: u8) -> Self
Create with custom settings. pending grows on demand (no
pre-reservation) — see Self::new.
Sourcepub fn untracked_evictions(&self) -> u64
pub fn untracked_evictions(&self) -> u64
Number of unacknowledged packets that the stream evicted from
its retransmit window because the window was full at on_send
time. Each eviction means the caller’s syscall succeeded
(bytes left this node) but the packet is no longer tracked
for retransmit — a NACK can no longer recover it. A non-zero
value indicates max_pending is undersized for the stream’s
sustained throughput. Operators should size up or apply
upstream backpressure rather than accepting silent loss.
Sourcepub fn next_expected(&self) -> u64
pub fn next_expected(&self) -> u64
Lowest sequence number we have not yet received. All sequences strictly below this value are contiguously received.
Sourcepub fn last_received_contiguous(&self) -> Option<u64>
pub fn last_received_contiguous(&self) -> Option<u64>
Highest contiguously-received sequence number, or None if no
packets have been received yet.
Sourcepub fn ack_seq(&self) -> u64
pub fn ack_seq(&self) -> u64
Get the current ack sequence (highest contiguously-received seq).
Returns 0 when nothing has been received yet — callers that need
to distinguish “received seq 0” from “received nothing” should use
Self::last_received_contiguous instead.
Trait Implementations§
Source§impl Debug for ReliableStream
impl Debug for ReliableStream
Source§impl Default for ReliableStream
impl Default for ReliableStream
Source§impl ReliabilityMode for ReliableStream
impl ReliabilityMode for ReliableStream
Source§fn on_send(&mut self, descriptor: Arc<RetransmitDescriptor>)
fn on_send(&mut self, descriptor: Arc<RetransmitDescriptor>)
Source§fn on_receive(&mut self, seq: u64) -> bool
fn on_receive(&mut self, seq: u64) -> bool
Source§fn build_nack(&self) -> Option<NackPayload>
fn build_nack(&self) -> Option<NackPayload>
Source§fn on_nack(&mut self, nack: &NackPayload) -> Vec<Arc<RetransmitDescriptor>>
fn on_nack(&mut self, nack: &NackPayload) -> Vec<Arc<RetransmitDescriptor>>
Arc clones
share the inner RetransmitDescriptor allocation; the
caller bumps the refcount instead of deep-cloning the
Vec<Bytes> of events.Source§fn get_timed_out(&mut self) -> Vec<Arc<RetransmitDescriptor>>
fn get_timed_out(&mut self) -> Vec<Arc<RetransmitDescriptor>>
Self::on_nack for the Arc-sharing contract.Source§fn take_failed(&mut self) -> bool
fn take_failed(&mut self) -> bool
true once
after a packet exhausts max_retries while still unacked — the
reliable layer can no longer recover that gap, so the caller
should signal a stream reset to the peer rather than let it stall
to a higher-level timeout. Default false (fire-and-forget never
gives up — it tracks nothing).Source§fn rx_ack_seq(&self) -> u64
fn rx_ack_seq(&self) -> u64
next_expected). The peer piggybacks this
on its window grants so the sender can prune (H-9). Default 0
(fire-and-forget tracks no sequence).Source§fn on_ack(&mut self, ack_seq: u64)
fn on_ack(&mut self, ack_seq: u64)
ack_seq has been received, so drop them from the retransmit
window (H-9). Without this, packets linger in pending on the
happy path until they spuriously time out and get resent (and,
post-H-3, spuriously give up). Default no-op.Source§fn can_send(&self) -> bool
fn can_send(&self) -> bool
true (fire-and-forget has no
congestion state). A reliable stream returns false once
in-flight reaches its cwnd, so the send path back-pressures and
paces to the cwnd under loss.