Skip to main content

NamespaceStream

Struct NamespaceStream 

Source
pub struct NamespaceStream {
    send: FramedSendStream,
    recv: FramedRecvStream,
    request_id: VarInt,
    draft: DraftVersion,
    stream_id: u64,
    origin: RequestOrigin,
    closed: bool,
    responded: bool,
}
Expand description

One SUBSCRIBE_NAMESPACE and everything answering it, on a bidirectional stream of their own.

Draft-16 Section 3.3: “This specification only specifies two uses of bidirectional streams, the control stream, which begins with CLIENT_SETUP, and SUBSCRIBE_NAMESPACE.” This is the second use, and the only request on this draft that has a stream at all — every other one is still written on the control stream and identified by its Request ID.

The stream matters because two of the four messages that travel on it carry no Request ID. Section 9.21 puts NAMESPACE “on the response stream of a SUBSCRIBE_NAMESPACE request” and Section 9.23 says the same of NAMESPACE_DONE; both carry a Track Namespace Suffix, relative to a prefix only this subscription knows. Without the stream they name nothing.

§Reading and writing go through the connection

This handle owns both halves of the stream but not the session, so the endpoint state machine and the observer stay where they were. Read with Connection::recv_on_namespace_stream, answer the peer with Connection::respond_ok_on_namespace_stream or Connection::respond_error_on_namespace_stream, report namespaces with Connection::send_on_namespace_stream, and withdraw with Connection::cancel_namespace_stream or Connection::finish_namespace_stream.

cancel, finish and peer_cancelled are on the handle because a caller may hold one without the connection. None of them moves the endpoint’s record of the subscription, which is why the connection carries a wrapper for each.

§Dropping this cancels the subscription, and correctly

Section 6.1: “A SUBSCRIBE_NAMESPACE can be cancelled by closing the stream with either a FIN or RESET_STREAM.” Dropping a send stream sends a FIN and dropping a receive stream sends STOP_SENDING, so a handle that falls out of scope performs the first of those two forms exactly. That is why there is no Drop impl here: on this draft the default is the cancellation, and drafts 17 to 19 need one only because they made a FIN mean something else.

What a drop cannot do is say so at the endpoint. It holds the stream and not the session, so the subscription stays where it was in the endpoint’s record while the stream it travelled on is gone. Call Connection::finish_namespace_stream wherever that record matters.

All fields are private so the shape can grow without breaking callers.

Fields§

§send: FramedSendStream§recv: FramedRecvStream§request_id: VarInt§draft: DraftVersion§stream_id: u64§origin: RequestOrigin§closed: bool

Whether this handle has already closed the stream, by either form.

§responded: bool

Whether a respond_* helper has written the answer on this stream. Only ever true on a RequestOrigin::Peer stream.

Implementations§

Source§

impl NamespaceStream

Source

pub fn request_id(&self) -> VarInt

The Request ID the SUBSCRIBE_NAMESPACE on this stream carries.

Source

pub fn stream_id(&self) -> u64

The transport-level stream identifier, the same one ClientEvent::StreamOpened reports.

Source

pub fn draft(&self) -> DraftVersion

The draft version this stream is framed for.

Source

pub fn origin(&self) -> RequestOrigin

Which side opened this stream.

RequestOrigin::Peer means this endpoint owes the answer and the respond_* helpers apply; RequestOrigin::Local means it is waiting for one.

Source

pub fn responded(&self) -> bool

Whether the answer has been written on this stream by one of the respond_* helpers.

Always false on a RequestOrigin::Local stream, which is answered by the peer rather than here.

Source

pub fn is_closed(&self) -> bool

Whether cancel or finish has already run on this handle.

Says nothing about the peer: a peer’s cancel is learned from peer_cancelled or from the next read.

Source

pub fn cancel(&mut self, code: u64) -> Result<(), ConnectionError>

Cancel the subscription by resetting the stream, handing the peer code.

The second of the two forms Section 6.1 allows. Both halves are shut — a QUIC bidirectional stream has two independent halves, so resetting only the send half would leave the peer free to keep writing namespaces nobody will read. The send half is reset with code and the receive half is stopped with the same value.

code is a plain u64 and has no default here, because draft-16 assigns none: its only registry of stream error codes is titled “Data Stream Reset Error Codes” and every entry in it is specified by Section 10.4.3, which is about closing subgroup streams. A namespace subscription’s stream is not a data stream, so a caller that wants to end one without choosing a number should use finish, the form that carries none.

This is the stream and nothing else. The endpoint’s record of the subscription does not move, so a namespace already in flight is still accepted after this returns. Connection::cancel_namespace_stream does both and is what a caller holding a connection should reach for.

Idempotent, and errors from a stream that was already reset or finished are swallowed: the subscription is cancelled either way.

§Errors

ConnectionError::Transport carrying TransportError::Write if code is outside the QUIC varint range (0..2^62). Nothing is sent in that case and the handle is not marked closed, so a caller can retry with a representable code.

Source

pub async fn finish(&mut self) -> Result<(), ConnectionError>

Cancel the subscription by finishing the send half cleanly.

The first of the two forms Section 6.1 allows, and the one that needs no error code. The receive half is left open on purpose: a publisher that has already written namespaces has them in flight, and stopping the half they arrive on would discard what was sent before the FIN.

Like cancel, this is the stream and nothing else. Connection::finish_namespace_stream is the same act with the endpoint’s record attached.

Idempotent.

Source

pub async fn peer_cancelled(&mut self) -> Result<Option<u64>, ConnectionError>

Wait for the peer to reset this stream, consuming nothing.

This sees one of Section 6.1’s two forms and not the other: a reset arrives here, a FIN arrives as Ok(None) from Connection::recv_on_namespace_stream. A caller that wants to observe both has to read.

Returns Ok(Some(code)) with the peer’s application error code, or Ok(None) meaning no reset is observable, now or ever — stop asking. A caller that re-polls after Ok(None) spins.

Records nothing at the endpoint; Connection::peer_cancelled_on_namespace_stream is the same wait with the record attached. Cancel-safe, and it grants no flow-control credit.

On WebTransport this always answers Ok(None): wtransport exposes no reset-only observable, so a WebTransport caller learns of a peer reset on its next read and not before.

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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

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

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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