Skip to main content

nanotify_core/
registry.rs

1use crate::{Notification, Notify, NotifyError, NotifyReceipt};
2use std::fmt;
3use std::sync::{Arc, OnceLock};
4
5/// 未显式指定命名渠道时使用的进程通知路由,不要求 YAML 声明 provider。
6pub const DEFAULT_PROVIDER_ID: &str = "default";
7
8static NOTIFIER: OnceLock<Arc<dyn Notify>> = OnceLock::new();
9
10/// 进程通知实现已经由业务初始化,不允许覆盖正在使用的实现。
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct AlreadyInitialized;
13
14impl fmt::Display for AlreadyInitialized {
15    /// 业务作用:报告重复初始化而不暴露业务实现或渠道配置。
16    ///
17    /// 参数说明:
18    /// - `formatter`:为错误输出目标。
19    ///
20    /// 返回:写入稳定错误说明,不包含通知内容。
21    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
22        formatter.write_str("notification implementation is already initialized")
23    }
24}
25
26impl std::error::Error for AlreadyInitialized {}
27
28/// 业务作用:由业务主动安装进程唯一通知实现,框架不创建客户端或解析通信协议。
29///
30/// 参数说明:
31/// - `provider`:是业务实现的共享 Notify,可在应用启动前或业务初始化阶段设置。
32///
33/// 返回:首次设置成功;重复设置返回 AlreadyInitialized,保留已发布实现且不发送消息。
34pub fn init(provider: Arc<dyn Notify>) -> Result<(), AlreadyInitialized> {
35    // 一次发布后保持稳定,避免在途通知跨实现切换、凭据被替换或重试改投另一服务。
36    NOTIFIER.set(provider).map_err(|_| AlreadyInitialized)
37}
38
39/// 业务作用:供调用方判断业务是否已经提供通知能力,不触发惰性初始化或外部 I/O。
40///
41/// 参数说明:无。
42///
43/// 返回:已初始化实现的共享引用;未设置时返回 None,不等待后续初始化。
44pub fn get() -> Option<&'static Arc<dyn Notify>> {
45    NOTIFIER.get()
46}
47
48/// 业务作用:有业务实现时直接异步调用,没有实现时忽略通知。
49///
50/// 参数说明:
51/// - `notification`:是调用方已经裁决和限制内容的消息。
52///
53/// 返回:未初始化为 Ok(None),已初始化为回执或业务实现返回的稳定错误;不自行排队、重试或启动任务。
54/// 直接调用者负责超时与异常边界;SQL 告警由宿主 worker 调用并施加隔离,不能在 SQL 完成路径等待本函数。
55pub async fn notify(notification: &Notification) -> Result<Option<NotifyReceipt>, NotifyError> {
56    let Some(provider) = get() else {
57        return Ok(None);
58    };
59    provider.notify(notification).await.map(Some)
60}