pub trait Notifier: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn send<'life0, 'life1, 'async_trait>(
&'life0 self,
payload: &'life1 NotificationPayload,
) -> Pin<Box<dyn Future<Output = Result<(), NotifierError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Plugin contract for delivering notifications.
One method + one associated function. Plugins live in their own
crates under ao-plugin-notifier-* starting in Phase C; the first
real plugin is stdout.
§Implementor responsibilities
- Never panic. Return a
NotifierErrorvariant instead. The engine traps errors but panics would tear down the polling task. - Respect a bounded timeout. HTTP plugins should default to 5s
and map overruns to
NotifierError::Timeout. The trait signature does not enforce this; it’s a hard convention. - Don’t hold locks across
.await. The engine callssendinline during a poll tick and a deadlocked plugin would wedge the whole loop. - Keep
sendside-effect-only. Payload mutation is out of scope — plugins receive&NotificationPayloadprecisely so they can’t rewrite history for downstream plugins in the same fan-out.
§Concurrency
Implementors must be Send + Sync because the registry stores
Arc<dyn Notifier> and the engine runs inside a tokio::spawn
task. Matches the rest of the ao-core plugin traits.
Required Methods§
Sourcefn name(&self) -> &str
fn name(&self) -> &str
Canonical name used in the notification-routing table.
Conventionally kebab-case ("stdout", "ntfy", "slack").
Must be stable across the plugin’s lifetime.
Sourcefn send<'life0, 'life1, 'async_trait>(
&'life0 self,
payload: &'life1 NotificationPayload,
) -> Pin<Box<dyn Future<Output = Result<(), NotifierError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn send<'life0, 'life1, 'async_trait>(
&'life0 self,
payload: &'life1 NotificationPayload,
) -> Pin<Box<dyn Future<Output = Result<(), NotifierError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Deliver one notification.
Returning Err does not crash the engine — the engine logs via
tracing::warn!, marks the ReactionOutcome as success = false, and proceeds to the next plugin in the fan-out.