pub struct Subscriber { /* private fields */ }Expand description
A live subscription to a track, used to read its groups.
Created via Consumer::subscribe, or
directly from a Producer for an in-process track. Carries this
subscriber’s Subscription preferences, which feed the producer’s aggregate.
§Local cursor vs wire preference
Group bounds exist at two levels, and setting one does not imply the other:
Self::set_groupslimits this subscriber’s reads, filtering exactly what this handle returns without changing the publisher’s demand.Subscription::start/Subscription::end, set viaSelf::update, are a request to the publisher. They’re aggregated across every live subscriber (earliest start, widest end), so they say what the publisher should send, not what this subscriber sees.
They stay separate because their scopes differ: a subscriber can’t filter by the aggregate, since another subscriber can widen it, and the publisher can’t honor a cursor it’s never told about. So setting only the cursor still transfers the skipped groups, and setting only the preference still returns groups another subscriber asked for. Set both to skip them and avoid the transfer.
The one place they meet is where the cursor comes from. A new subscriber’s cursor is
floored at the group its own subscription named (or 0), and its
Subscription::max_age decides what above the floor is worth delivering. Every later
move is the caller’s.
Implementations§
Source§impl Subscriber
impl Subscriber
Sourcepub fn info(&self) -> &Info
pub fn info(&self) -> &Info
The track’s Info, resolved when the subscription was established.
Free, unlike Consumer::query: subscribing already waited for the info
(SUBSCRIBE_OK on the wire), so a subscriber always has it.
Sourcepub fn broadcast(&self) -> &Info
pub fn broadcast(&self) -> &Info
The broadcast this track belongs to, as reached through the handle it came from.
Its path is what a catalog’s relative broadcast
references resolve against.
Sourcepub fn control(&self) -> Control
pub fn control(&self) -> Control
Create a handle for updating this subscriber’s delivery preferences.
Sourcepub fn poll_recv_group(
&mut self,
waiter: &Waiter,
) -> Poll<Result<Option<Consumer>>>
pub fn poll_recv_group( &mut self, waiter: &Waiter, ) -> Poll<Result<Option<Consumer>>>
Poll for the next group in arrival order, without blocking.
Returns each group it delivers exactly once, in the order it landed on the wire,
which may be out of sequence due to network reordering or loss. Use
Self::ordered if you only want groups whose sequence number is higher than any
previously returned.
Groups are semi-reliable, and the Subscription::max_age budget is the other
thing (alongside eviction and a moving start) that decides which of them arrive:
one that has drifted further behind the live edge than the budget tolerates is
skipped rather than handed over, so a single poll walks off a whole backlog. The
default is Duration::ZERO, which takes the live
edge and writes the rest off; raise it to read history. Self::set_groups and
Subscription::start are filters, not exemptions: backfill needs a budget that
covers it. Consumer::fetch_group is the way to ask for one old group outright.
The budget remains attached to a returned group: if it stalls while newer data
advances, its pending frame read ends with Error::Old.
Honors the group range set by Self::set_groups:
a group beyond the cap is parked (not dropped) and re-offered once the cap rises
(lowest sequence first), without blocking in-range groups that arrive behind it.
A parked group that the producer evicts or expires in the meantime is dropped,
so parking never outlives the track’s cache policy.
Returns Poll::Ready(Ok(Some(group))) when a group is available,
Poll::Ready(Ok(None)) when the track is finished,
Poll::Ready(Err(e)) when the track has been aborted, or
Poll::Pending when no group is available yet.
Sourcepub async fn recv_group(&mut self) -> Result<Option<Consumer>>
pub async fn recv_group(&mut self) -> Result<Option<Consumer>>
Receive the next group in arrival order.
Every group is returned exactly once, in the order it landed on the wire, which may
be out of sequence due to network reordering or loss. Use Self::ordered if you
only want groups whose sequence number is higher than any previously returned.
See Self::poll_recv_group for how Self::set_groups applies.
Sourcepub fn poll_recv_datagram(
&mut self,
waiter: &Waiter,
) -> Poll<Result<Option<Datagram>>>
pub fn poll_recv_datagram( &mut self, waiter: &Waiter, ) -> Poll<Result<Option<Datagram>>>
Poll for the next datagram in arrival order, without blocking.
Datagrams are a separate best-effort channel from groups (see
Producer::append_datagram); they share only the sequence namespace, and
neither cursor moves the other. A consumer that falls too far behind silently
loses the oldest datagrams.
Returns Poll::Ready(Ok(Some(datagram))) when one is available,
Poll::Ready(Ok(None)) when the track is finished, Poll::Ready(Err(e)) when the track
is aborted, or Poll::Pending when none is buffered yet.
Sourcepub async fn recv_datagram(&mut self) -> Result<Option<Datagram>>
pub async fn recv_datagram(&mut self) -> Result<Option<Datagram>>
Receive the next datagram in arrival order.
A best-effort channel parallel to Self::recv_group; the two share only the sequence
namespace. To receive both concurrently from one subscriber, poll
Self::poll_recv_group and Self::poll_recv_datagram together in a single poll
closure (sequential &mut borrows), rather than awaiting the two recv futures at once.
Sourcepub fn ordered(self) -> Ordered
pub fn ordered(self) -> Ordered
Read this track’s groups in sequence order instead of arrival order.
Consumes the subscriber, so one handle carries exactly one cursor: an
arrival-order Subscriber or a sequence-order Ordered, never both at once.
The two advance independently, and interleaving them produces a group stream that
is neither, which is why the choice is a handle rather than a method.
Datagrams come along: they are a separate cursor either way, so the choice of group order says nothing about them.
Sourcepub fn is_clone(&self, other: &Self) -> bool
pub fn is_clone(&self, other: &Self) -> bool
Whether other was cloned from this subscriber (shares the same underlying state).
Sourcepub fn poll_finished(&mut self, waiter: &Waiter) -> Poll<Result<u64>>
pub fn poll_finished(&mut self, waiter: &Waiter) -> Poll<Result<u64>>
Poll for the track’s declared final sequence, without blocking.
Sourcepub async fn finished(&mut self) -> Result<u64>
pub async fn finished(&mut self) -> Result<u64>
Block until the track declares its end, returning the exclusive final sequence (also the total group count), or the cause on an abort.
Resolves as soon as the boundary is known, which may be ahead of the live edge
when the producer finished via Producer::finish_at. This reports the declared
end, not that every group has arrived: drive Self::recv_group (or
Ordered::next_group) until it yields None to observe the track fully drained.
Sourcepub fn set_groups(&mut self, groups: impl RangeBounds<u64>)
pub fn set_groups(&mut self, groups: impl RangeBounds<u64>)
Limit subsequent reads to these group sequences without rewinding read progress.
2..=5 includes groups 2 through 5; 2..5 excludes group 5. An omitted
start preserves the current floor, and an omitted end removes the cap.
Groups above the end remain buffered and can be read after raising the cap.
This changes only local delivery; use Subscription::with_groups and
Self::update to change the requested groups.
Sourcepub fn subscription(&self) -> Subscription
pub fn subscription(&self) -> Subscription
This subscriber’s current preferences.
Sourcepub fn update(&mut self, subscription: Subscription) -> Result<()>
pub fn update(&mut self, subscription: Subscription) -> Result<()>
Replace this subscriber’s delivery preferences.
Stored verbatim; the publisher’s max age window is applied to the aggregate, not
here (see Producer::subscription). Returns Error::Closed if the track
already ended; the update is meaningless at that point and can usually be ignored.