Skip to main content

Stream

Struct Stream 

Source
pub struct Stream { /* private fields */ }
Available on crate feature std only.
Expand description

Stream - multiplexed data channel within a session

Implementations§

Source§

impl Stream

Source

pub fn new(id: StreamId) -> Self

Create a new stream

Source

pub fn reset_rto(&self)

Reset the RTT estimator (Phase 4 / QUIC §9.4): a migration path switch lands on a different network, so the old RTT must not carry over. A poisoned lock is recovered by taking the inner value — the RTO is a heuristic.

Source

pub fn id(&self) -> StreamId

Get stream ID

Source

pub async fn state(&self) -> StreamState

Get current state

Source

pub fn priority(&self) -> u32

Get priority

Source

pub fn set_priority(&self, priority: u32)

Set priority

Source

pub fn peer_send_window(&self) -> u32

Bytes the peer currently allows us to send.

Source

pub fn try_consume_send_window(&self, n: u32) -> bool

Atomically reserve n bytes from the peer’s send window. Returns true if the reservation succeeded (and the window was decremented); false if the window doesn’t have enough capacity — caller must wait for a WINDOW_UPDATE.

Source

pub fn apply_peer_window_update(&self, credit: u32)

Process an inbound WINDOW_UPDATE from the peer. The payload is a relative credit — the number of bytes the peer’s application just consumed and is therefore newly willing to receive. We add it to the send window (saturating at MAX_SEND_WINDOW so a misbehaving peer’s inflated credit cannot overflow the counter).

Relative credit (vs. an absolute window) is what makes flow control correct for a session of any length: the sender’s window is initial + Σ credit_granted − Σ bytes_sent = initial + consumed − sent, so the receiver’s outstanding (unconsumed) bytes sent − consumed are bounded by initial. An absolute u32 window could not express this for sessions exceeding 4 GiB and over-committed the receiver’s buffer.

Source

pub fn local_recv_window(&self) -> u32

Bytes the local side has granted the peer.

Source

pub fn record_app_consumed(&self, n: u32) -> Option<u32>

Record that the application has actually consumed n bytes from this stream (called by the receive delivery task on real drainage, not on routing). Accumulates the consumed bytes and, once the unreported total crosses half the initial window, returns Some(credit) — the relative credit to advertise in a WINDOW_UPDATE (the peer adds it to its send window). The half-window threshold trades update frequency against peer stalls.

Source

pub fn stage_window_update_credit(&self, credit: u32)

Stage relative flow-control credit to be flushed by the send loop. Called by the receive delivery task after it credits real app consumption. Credits accumulate additively (saturating at u32::MAX) rather than overwriting, so several grants landing between two send-loop flushes are summed instead of lost — the send loop is the single emitter (epoch-safe), and it may run arbitrarily after a grant.

Source

pub fn take_pending_window_update(&self) -> Option<u32>

Take all staged credit (swaps the slot back to 0). The send loop calls this each drain pass and emits one WINDOW_UPDATE carrying the summed credit if Some.

Source

pub async fn send_reliable( &self, data: Bytes, ) -> Result<SequenceNumber, CoreError>

Queue data for sending with reliability.

Returns the gap-free stream_offset assigned to this chunk (the reassembly / SACK key). The wire packet number is assigned later, at send time, by the data pump (① — Phase 4). Fails closed with CoreError::StreamError once the u32 offset space is exhausted (T4.5) — the acquired backpressure permit is released on that path so the semaphore accounting stays correct.

Source

pub async fn send_unreliable(&self, data: Bytes)

Queue data for unreliable sending. Fire-and-forget; the wire packet number is assigned at send time by the data pump (① — Phase 4).

Source

pub async fn poll_send(&self, cwnd_budget: u64) -> Option<OutboundSegment>

Get the next segment to (re)transmit, or None if nothing is due.

cwnd_budget is how many bytes of new data the congestion window currently permits. Retransmissions ignore it — loss recovery must always proceed — but a first transmission is withheld (None) when it would exceed the budget, so the next drain resumes once ACKs free the window. Pass u64::MAX to disable the limit.

Source

pub async fn ack(&self, stream_offset: SequenceNumber) -> Option<(Instant, u64)>

Mark a sequence number as acknowledged. Returns the timestamp when the packet was originally sent and its size, if found.

Source

pub async fn mark_unsent(&self, stream_offset: SequenceNumber)

Reset a still-buffered reliable segment’s send timestamp so the next poll_send re-offers it immediately (as an unsent segment) rather than waiting a full RTO for the retransmit pass. Used when a send attempt failed after poll_send had already stamped sent_at — the bytes never reached the wire, so the segment must not be treated as in-flight. No-op if the segment was already acknowledged and removed.

Source

pub async fn received_sack(&self, ack_delay_us: u32) -> Option<Sack>

Build a Sack describing exactly the reliable-data sequences this stream currently holds, derived from the reorder state (single source of truth): the contiguous delivered run [0, recv_sequence-1] as one range, plus one range per out-of-order island still buffered in recv_buffer. Returns None if nothing has been received yet.

Because the SACK is derived from what the reorder buffer actually holds, the receiver never SACKs a sequence it has dropped (the SACK-without-data hazard of a separate received-set). ack_delay_us: the caller’s measured value, or — when 0 — a coarse now − last_data_recv_at so the on-wire field is populated. The range set is capped to crate::transport::sack::MAX_SACK_RANGES by Sack::from_inclusive_ranges so it always decodes at the peer.

Source

pub async fn on_sack(&self, sack: &Sack) -> SackResult

Process a received SACK, retiring every buffered reliable segment whose gap-free stream_offset the SACK covers (A.5; the SACK ranges are over stream_offset, not the control-frame-holed wire sequence). Returns a SackResult listing the newly-retired segments so the caller can feed congestion control / the RTT estimator per segment.

RTT is sampled here (Karn’s algorithm) only for segments that were never retransmitted (retries == 0); RetiredSegment::was_retransmit marks the rest so the caller does not double-count or use an ambiguous sample.

This is a cumulative retire: a SACK re-acks every still-buffered offset it covers, so a lost ACK no longer strands a segment — the next SACK retires it. No loss detection / fast-retransmit here — that is L1-B.

Source

pub async fn accept_in_order( &self, sequence: SequenceNumber, payloads: Vec<Bytes>, ) -> Vec<Bytes>

Accept reliable data payloads carried at sequence and return the contiguous in-order run now deliverable to the application, in ascending order. The returned Vec is empty when this is a future hole (buffered for later), a duplicate, or refused for capacity.

payloads is normally one element (a single RELIABLE frame); a COALESCED bundle passes its sub-payloads so the whole bundle occupies one cursor position. This is the single source of truth for receive ordering: the live data pump routes every reliable app payload through here so the app sees the reliable stream strictly in sequence order even over a reordering (UDP) path. Out-of-order segments are held in recv_buffer (bounded by MAX_RECV_REORDER); the data-arrival instant is stamped for the SACK ack_delay_us.

Source

pub fn recv_reorder_bytes(&self) -> usize

Total payload bytes currently held in the out-of-order reorder buffer (H-3). Bounded by MAX_RECV_REORDER_BYTES; exposed so the byte bound is observable/testable.

Source

pub async fn on_receive(&self, sequence: SequenceNumber, data: Bytes)

Pull-API adapter over accept_in_order: buffer a single reliable payload for in-order reassembly and push the released run into recv_ready for recv / try_recv. (Not used by the live session pump, which consumes the returned run directly; retained for the pull-style read API.)

Source

pub async fn recv(&self) -> Option<Bytes>

Read data from the stream (async, waits if no data available)

Source

pub async fn try_recv(&self) -> Option<Bytes>

Try to read data without waiting

Source

pub async fn finish(&self)

Mark local side as finished (no more data to send)

Source

pub async fn on_remote_finish(&self)

Mark remote side as finished

Source

pub async fn pending_send_count(&self) -> usize

Get number of pending send chunks

Source

pub async fn pending_recv_count(&self) -> usize

Get number of pending receive chunks

Source

pub fn is_closed(&self) -> bool

Check if stream is closed

Trait Implementations§

Source§

impl Debug for Stream

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CompatExt for T

Source§

fn compat(self) -> Compat<T>
where T: Sized,

Applies the Compat adapter by value. Read more
Source§

fn compat_ref(&self) -> Compat<&T>

Applies the Compat adapter by shared reference. Read more
Source§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the Compat adapter by mutable reference. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T, UT> HandleAlloc<UT> for T
where T: Send + Sync,

Source§

fn new_handle(value: Arc<T>) -> Handle

Create a new handle for an Arc value Read more
Source§

unsafe fn clone_handle(handle: Handle) -> Handle

Clone a handle Read more
Source§

unsafe fn consume_handle(handle: Handle) -> Arc<T>

Consume a handle, getting back the initial Arc<> Read more
Source§

unsafe fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more