Skip to main content

StreamAction

Enum StreamAction 

Source
#[non_exhaustive]
pub enum StreamAction { Open, Reject { code: u64, }, OpenAfter(Duration), SerializeAfter(StreamKey), }
Expand description

What to do with a unidirectional stream.

Returned from both ProxyHook::on_stream_open and ProxyHook::on_stream_header. The observable effect of Reject differs between the two, and both are honest:

  • At open, no peer stream is created at all.
  • At header, the peer stream already exists — it is opened before any byte of the source is read, whether that is in the accept loop or, for a stream whose open was deferred by Self::OpenAfter, in the stream’s own task once the delay has elapsed — so it is reset with code having carried zero payload bytes, and the source is stopped with code.

The same asymmetry decides where Self::OpenAfter is legal: it is a decision about when the peer stream comes into existence, so only the open site can take it. Self::SerializeAfter is a decision about when the first byte is written, which both sites can still take.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Open

Forward the stream normally.

§

Reject

Do not forward this stream. The source is stopped with code.

Fields

§code: u64

The application error code.

§

OpenAfter(Duration)

Forward the stream, but do not open the peer stream until after has elapsed.

Valid at ProxyHook::on_stream_open only. By ProxyHook::on_stream_header the peer stream already exists — it is opened before the first source byte is read, which is what makes a header arrive at all — so there is nothing left to defer and the header site refuses it with Refusal::WrongSite, reported as ProxyEvent::ActionRefused. It is refused rather than quietly ignored: a hook that asks for a deferral this crate cannot perform is told so, and the stream is forwarded unchanged. Delaying a stream’s opening on something only its header reveals — its track alias, say — would want the header site, and is therefore not expressible in this release: the open decision has to be taken before a byte is read.

This models a relay that is slow to accept a subscription rather than one that is slow to send: the subscriber observes no stream at all for after, not an open-but-idle one. For the latter, see Self::SerializeAfter, which is valid at both sites.

The deferral is a wire-visible one, not a bookkeeping note: the peer stream is not opened and the source is not read until after has elapsed, so a stream opened later and not deferred reaches the peer first.

§

SerializeAfter(StreamKey)

Open the peer stream now, but write nothing on it until the stream named by the key has ended.

Head-of-line simulation: two streams that a relay would have interleaved are forced into sequence, so a scenario can reproduce a subscriber that stalls behind an unrelated group.

Valid at both stream sites — it defers the first write, not the stream’s existence.

One stream is exempt, and it is worth knowing before writing a scenario against it: on the drafts whose control plane is a pair of unidirectional streams, a stream that turns out to be one of them is not held. Holding a control stream’s first write would hold SETUP, and the session with it. The open site cannot tell in advance — which stream it is is decided by the first varint on it, read after the decision has been taken — so the decision is admitted and then does not apply to that one stream.

The key comes from StreamCtx::key on a stream the hook was shown earlier. A key naming a stream that has already ended, or that never existed in this session, proceeds immediately and reports Impairment { SerializeTargetUnknown } once — a scenario cannot deadlock a stream by naming the wrong one, and the mistake is reported rather than silently waited out.

Trait Implementations§

Source§

impl Clone for StreamAction

Source§

fn clone(&self) -> StreamAction

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for StreamAction

Source§

impl Debug for StreamAction

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Eq for StreamAction

Source§

impl PartialEq for StreamAction

Source§

fn eq(&self, other: &StreamAction) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for StreamAction

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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<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