pub struct Subscription<T: Send + Sync + 'static> { /* private fields */ }Expand description
Latest-value state cell with a bounded every-change feed.
Subscription uses a two-plane implementation. The Ractor actor owns only subscribe,
unsubscribe, close, terminal delivery, and the registry that is periodically published as an
ArcSwap slot-table snapshot. State transitions run on the caller thread.
The lossless data plane is a sequence-claimed ring: each writer claims a global sequence,
waits for its publish turn, writes the ring slot, stores the ArcSwap mirror, publishes an
internal (sequence, value) snapshot, wakes current subscribers, and then returns. Under
SubscriptionOverflow::Backpressure, producers wait outside the actor while any active
subscriber cursor would lag past the logical capacity. Subscribers consume by cursor in total
sequence order, so they see no gaps or duplicates.
Subscribe has no actor-serialized-set gap. The control actor first publishes the new
slot-table snapshot, then seeds the slot from the current published (sequence, value) and sets
the cursor to sequence + 1; any writer that races after registration is either represented by
the seed or consumed from the ring.
update uses ArcSwap::compare_and_swap under the write publication turn. The update function
may be re-invoked if a concurrent writer wins the CAS race, matching the usual Ref/atomic
update contract.
Implementations§
Source§impl<T: Send + Sync + 'static> Subscription<T>
impl<T: Send + Sync + 'static> Subscription<T>
Sourcepub fn new(
initial: T,
capacity: usize,
overflow: SubscriptionOverflow,
) -> StreamResult<Self>
pub fn new( initial: T, capacity: usize, overflow: SubscriptionOverflow, ) -> StreamResult<Self>
Create a subscription initialized to initial.
Panics if capacity == 0.
Sourcepub fn get(&self) -> Arc<T> ⓘ
pub fn get(&self) -> Arc<T> ⓘ
Return the current immutable snapshot without sending an actor message.
Sourcepub fn get_cloned(&self) -> Twhere
T: Clone,
pub fn get_cloned(&self) -> Twhere
T: Clone,
Return a cloned value using ArcSwap::load()’s guarded read path.
This avoids cloning the Arc itself on the hot read path. For scalar Copy/cheap-Clone
values, this is the fair equivalent of JVM refs returning the value directly; use
Subscription::get when the caller wants an owned snapshot shared by Arc.
Sourcepub fn set(&self, value: T) -> StreamResult<()>
pub fn set(&self, value: T) -> StreamResult<()>
Set the state and wait for the transition to be accepted according to the overflow policy.
Sourcepub fn set_eventually(&self, value: T) -> StreamResult<()>
pub fn set_eventually(&self, value: T) -> StreamResult<()>
Set the state on the caller thread.
With SubscriptionOverflow::Backpressure, this may still park the caller until subscriber
cursors make ring capacity available. It does not send an actor message.
Sourcepub fn update<F>(&self, update: F) -> StreamResult<()>
pub fn update<F>(&self, update: F) -> StreamResult<()>
Update the state atomically and wait for the transition to be accepted.
The update function may be called more than once if a concurrent writer wins the CAS race.
Sourcepub fn update_eventually<F>(&self, update: F) -> StreamResult<()>
pub fn update_eventually<F>(&self, update: F) -> StreamResult<()>
Update the state atomically on the caller thread.
The update function may be called more than once if a concurrent writer wins the CAS race.
Sourcepub fn close(&self) -> StreamResult<()>
pub fn close(&self) -> StreamResult<()>
Close the subscription, re-emitting the current final snapshot to current subscribers.
Sourcepub fn close_with(&self, final_value: T) -> StreamResult<()>
pub fn close_with(&self, final_value: T) -> StreamResult<()>
Set a final value, then close the subscription in one control-plane turn.
Source§impl<T: Clone + Send + Sync + 'static> Subscription<T>
impl<T: Clone + Send + Sync + 'static> Subscription<T>
Sourcepub fn changes(&self) -> Source<T>
pub fn changes(&self) -> Source<T>
A bounded source of the current value followed by every accepted change.
Under SubscriptionOverflow::Backpressure, every subscriber observes every change. Under
DropNew, slow subscribers may miss changes. Under Fail, a full subscriber fails with
StreamError::Failed.