pub struct Notifier { /* private fields */ }Expand description
The handle other modules call.
A venture gets one from crate::Notifications::notifier and hands it
to its own modules; it is a cheap clone and shares the mounted module’s
ports, so it is usable only after Harness::router has built the
module’s router.
Implementations§
Source§impl Notifier
impl Notifier
Sourcepub fn context(&self) -> Option<&Arc<ModuleContext>>
pub fn context(&self) -> Option<&Arc<ModuleContext>>
The mounted context, once Harness::router has built the module’s
router. None before that.
Sourcepub async fn notify(
&self,
db: &dyn Database,
account_id: &str,
category: &str,
message: impl Into<Message>,
) -> Result<Enqueued, NotifyError>
pub async fn notify( &self, db: &dyn Database, account_id: &str, category: &str, message: impl Into<Message>, ) -> Result<Enqueued, NotifyError>
Prepares one notification for every device account_id has.
Writes nothing: append Enqueued::statements to your own
db.batch_atomic(..) so the notification is durable exactly when your
state change is, then call Notifier::deliver_now.
message is either a Notification the caller wrote — today’s
path, unchanged, and the one a single-language venture uses — or a
Localizable naming a message in the venture’s catalog, which
the drain renders per recipient (#190).
§Errors
NotifyError::UnknownCategory for a category the venture did
not declare, NotifyError::InvalidData for a non-object
data, NotifyError::NoCatalog for a localizable message in a
venture with no catalog, and NotifyError::Database when a read
fails.
Sourcepub async fn notify_now(
&self,
db: &dyn Database,
scope: &Scope,
account_id: &str,
category: &str,
message: impl Into<Message>,
) -> Result<Enqueued, NotifyError>
pub async fn notify_now( &self, db: &dyn Database, scope: &Scope, account_id: &str, category: &str, message: impl Into<Message>, ) -> Result<Enqueued, NotifyError>
Notifier::notify for a caller with no state change of its own:
commits the outbox rows in their own batch and attempts immediate
delivery. The event-bus entry point is this.
§Errors
As Notifier::notify, plus NotifyError::Database when the
batch fails.
Sourcepub async fn announce(&self, scope: &Scope, enqueued: &Enqueued)
pub async fn announce(&self, scope: &Scope, enqueued: &Enqueued)
Announces a just-committed inbox row to the account’s room, when
the venture wired Realtime.
Call it after your batch commits, for the same reason
Notifier::deliver_now says so: a client that received the event
will read the inbox, and the row has to be there.
Notifier::notify_now does it for you.
Deliberately not part of the drain. The drain runs only when there are push rows, and the account this matters most to — no device, or push refused — has none. A failure is logged and swallowed: a live update is an optimisation over the client’s own polling, and losing one must never fail the caller’s write. Announces a just-committed inbox row, and says on the bus that the catalog could not render part of the message (#190).
The two are here together because this is the first point in the
batch API at which there is a Scope to emit an event in:
Notifier::notify runs inside somebody else’s transaction and
has none. A caller that batches its own statements and never calls
this still learns about a missing translation from the drain, which
reports one per delivery — but an account with no device and no
mailbox has no delivery, so call it.
Sourcepub fn deliver_now(&self, scope: &Scope)
pub fn deliver_now(&self, scope: &Scope)
Attempts immediate delivery on the request’s Defer.
Call it after your batch commits. Nothing is lost if the isolate dies first: the venture’s scheduled drain picks the rows up on the next tick.
Sourcepub async fn drain(&self, scope: &Scope) -> Result<DrainReport, NotifyError>
pub async fn drain(&self, scope: &Scope) -> Result<DrainReport, NotifyError>
Delivers every due outbox row this drainer can lease, through the mounted module’s ports.
The whole delivery policy lives here: Delivered completes the
row, Unregistered deletes the row and the subscription,
Rejected and NotConfigured dead-letter it, and Transient
retries with backoff — never before the retry_after the provider
asked for — to a bound, then dead-letters.
§Errors
NotifyError when the module is not mounted, a port is missing,
or the claim itself fails. A per-row failure never aborts the
pass: it is counted in DrainReport::failed and the row keeps
its lease until it expires.
Sourcepub async fn drain_with(
&self,
ctx: &ModuleContext,
scope: &Scope,
) -> Result<DrainReport, NotifyError>
pub async fn drain_with( &self, ctx: &ModuleContext, scope: &Scope, ) -> Result<DrainReport, NotifyError>
Notifier::drain through the ports of the context handed in.
This is what scheduled work must use. A cron invocation builds no router, so on a cold isolate there is no mounted context to drain through at all, and on a warm one draining through the parked context means using some earlier request’s database handle.
§Errors
As Notifier::drain, minus NotifyError::NotMounted: this
entry point needs no mounted module.