pub struct Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,{ /* private fields */ }Expand description
A notifier is a notification broadcaster. It receives notifications from upstream parents and broadcasts those downstream to its children listeners. Symmetrically, it receives subscriptions from its downward listeners, compounds those internally and pushes upward the subscriptions resulting of the compounding, if any, to the parents.
§Enabled event types
A notifier has a set of enabled event type (see EventType). It only broadcasts notifications whose
event type is enabled and drops the others. The same goes for subscriptions.
Each subscriber has a set of enabled event type. No two subscribers may have the same event type enabled. The union of the sets of all subscribers should match the set of the notifier, though this is not mandatory.
§Mutation policies
The notifier is built with some mutation policies defining how an processed listener mutation must be propagated to the parent.
§Architecture
§Internal structure
The notifier notably owns:
- a vector of
DynCollector - a vector of
Subscriber - a pool of
Broadcaster - a map of
Listener
Collectors and subscribers form the scaffold. They are provided to the ctor, are immutable and share its lifespan. Both do materialize a connection to the notifier parents, collectors for incoming notifications and subscribers for outgoing subscriptions. They may usually be paired by index in their respective vector but this by no means is mandatory, opening a field for special edge cases.
The broadcasters are built in the ctor according to a provided count. They act as a pool of workers competing for the processing of an incoming notification.
The listeners are managed dynamically through registration/unregistration calls.
§External conformation
The notifier is designed so that many instances can be interconnected and form a DAG of notifiers.
However, the notifications path from the root all the way downstream to the final clients is forming a tree,
not a DAG. This is because, for a given type of notification (see EventType), a notifier has at most a single
parent provider.
The same is symmetrically true about subscriptions which travel upstream from clients to the root along a tree,
meaning that, for a given type of subscription (see EventType), a notifier has at most a single subscriber,
targeting a single parent.
§Special considerations
A notifier is built with a specific set of enabled event types. It is however possible to manually subscribe to a disabled scope and thus have a custom-made collector of the notifier receive notifications of this disabled scope, allowing some handling of the notification into the collector before it gets dropped by the notifier.
Implementations§
Source§impl<N, C> Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,
impl<N, C> Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,
pub fn new( name: &'static str, enabled_events: EventSwitches, collectors: Vec<DynCollector<N>>, subscribers: Vec<Arc<Subscriber>>, subscription_context: SubscriptionContext, broadcasters: usize, policies: MutationPolicies, ) -> Self
pub fn with_sync( name: &'static str, enabled_events: EventSwitches, collectors: Vec<DynCollector<N>>, subscribers: Vec<Arc<Subscriber>>, subscription_context: SubscriptionContext, broadcasters: usize, policies: MutationPolicies, _sync: Option<Sender<()>>, ) -> Self
pub fn subscription_context(&self) -> &SubscriptionContext
pub fn enabled_events(&self) -> &EventSwitches
pub fn start(self: Arc<Self>)
pub fn register_new_listener( &self, connection: C, lifespan: ListenerLifespan, ) -> ListenerId
Sourcepub fn try_renew_subscriptions(&self) -> Result<()>
pub fn try_renew_subscriptions(&self) -> Result<()>
Resend the compounded subscription state of the notifier to its subscribers (its parents).
The typical use case is a RPC client reconnecting to a server and resending the compounded subscriptions of its listeners.
pub fn try_start_notify(&self, id: ListenerId, scope: Scope) -> Result<()>
pub fn try_execute_subscribe_command( &self, id: ListenerId, scope: Scope, command: Command, ) -> Result<()>
pub fn try_stop_notify(&self, id: ListenerId, scope: Scope) -> Result<()>
pub fn unregister_listener(&self, id: ListenerId) -> Result<()>
pub async fn join(&self) -> Result<()>
Trait Implementations§
Source§impl<N, C> Notify<N> for Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,
impl<N, C> Notify<N> for Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,
Source§impl<N, C> SubscriptionManager for Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,
impl<N, C> SubscriptionManager for Notifier<N, C>where
N: Notification,
C: Connection<Notification = N>,
fn start_notify<'life0, 'async_trait>(
&'life0 self,
id: ListenerId,
scope: Scope,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn stop_notify<'life0, 'async_trait>(
&'life0 self,
id: ListenerId,
scope: Scope,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn execute_subscribe_command<'life0, 'async_trait>(
&'life0 self,
id: ListenerId,
scope: Scope,
command: Command,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Auto Trait Implementations§
impl<N, C> Freeze for Notifier<N, C>
impl<N, C> !RefUnwindSafe for Notifier<N, C>
impl<N, C> Send for Notifier<N, C>
impl<N, C> Sync for Notifier<N, C>
impl<N, C> Unpin for Notifier<N, C>
impl<N, C> !UnwindSafe for Notifier<N, C>
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<S> CastArc for Swhere
S: CastFromSync + ?Sized,
impl<S> CastArc for Swhere
S: CastFromSync + ?Sized,
Source§impl<T> CastFrom for Twhere
T: Any + 'static,
impl<T> CastFrom for Twhere
T: Any + 'static,
Source§fn ref_any(&self) -> &(dyn Any + 'static)
fn ref_any(&self) -> &(dyn Any + 'static)
Any, which is backed by the type implementing this trait.Source§fn mut_any(&mut self) -> &mut (dyn Any + 'static)
fn mut_any(&mut self) -> &mut (dyn Any + 'static)
Any, which is backed by the type implementing this trait.Source§impl<T> CastFromSync for T
impl<T> CastFromSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more