pub struct Subscribable<T: Pod> { /* private fields */ }Expand description
Clone-able handle for spawning Subscribers.
Send this to other threads and call subscribe
to create independent consumers.
Implementations§
Source§impl<T: Pod> Subscribable<T>
impl<T: Pod> Subscribable<T>
Sourcepub fn subscribe(&self) -> Subscriber<T>
pub fn subscribe(&self) -> Subscriber<T>
Create a subscriber that will see only future messages.
Sourcepub fn subscribe_lossy(&self) -> Subscriber<T>
pub fn subscribe_lossy(&self) -> Subscriber<T>
Create a subscriber that never gates the publisher.
On a bounded channel, subscribe registers the
subscriber for backpressure: the publisher refuses to overwrite a slot
this subscriber has not read yet. A lossy subscriber opts out of
that guarantee. The publisher ignores it entirely, and if it falls
behind it observes TryRecvError::Lagged
with an exact skip count, exactly as on a lossy channel.
This lets a single ring carry consumers with different delivery contracts: a risk engine that must see every message, and telemetry that must never stall the publisher, reading the same sequence numbers.
use photon_ring::channel_bounded;
let (mut p, s) = channel_bounded::<u64>(4, 0);
let mut critical = s.subscribe(); // gates the publisher
let mut telemetry = s.subscribe_lossy(); // never gates it
p.publish(1);
assert_eq!(critical.try_recv(), Ok(1));
assert_eq!(telemetry.try_recv(), Ok(1));On a lossy channel this is identical to subscribe,
since no subscriber gates the publisher there.
Sourcepub fn subscribe_from_oldest(&self) -> Subscriber<T>
pub fn subscribe_from_oldest(&self) -> Subscriber<T>
Create a subscriber starting from the oldest available message still in the ring (or 0 if nothing published yet).
Note that on a bounded channel the no-loss guarantee only applies from
the subscription point forward. This starts at a sequence the publisher
was already entitled to overwrite, and registering cannot retroactively
reserve it, so the retained history it starts from may be lapped before
it is read. Use subscribe if you need the guarantee
from the first message you see.
The converse also holds: once the publisher observes this subscriber’s
tracker, the retained history counts as unread, so on a bounded channel
the publisher can be gated until up to a full ring of messages is
drained. Attach a replay consumer this way only if it will drain
promptly; a tap that must never stall the publisher should use
subscribe_lossy instead.
Sourcepub fn subscribe_tracked(&self) -> Subscriber<T>
pub fn subscribe_tracked(&self) -> Subscriber<T>
Create a subscriber with an active cursor tracker.
Use this when the subscriber will participate in a
DependencyBarrier as an upstream consumer.
On bounded channels, this behaves identically to
subscribe() — those subscribers already have
trackers.
On lossy channels, subscribe() omits the
tracker (zero overhead for the common case). This method creates a
standalone tracker so that a DependencyBarrier can read the
subscriber’s cursor position. The tracker is not registered
with the ring’s backpressure system — it is purely for dependency
graph coordination.