#[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 withcodehaving carried zero payload bytes, and the source is stopped withcode.
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
Open
Forward the stream normally.
Reject
Do not forward this stream. The source is stopped with 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
impl Clone for StreamAction
Source§fn clone(&self) -> StreamAction
fn clone(&self) -> StreamAction
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more