ek-core 0.5.0

Business-agnostic plugin host and actor-over-bus runtime on top of ek-event: capability index with runtime service discovery, per-plugin actor workers, dynamic add/remove with lifecycle broadcasts, one-shot ask/ask_service with contract gates, panic quarantine, five-step close.
Documentation
//! 生命周期与服务改版的事件类型串(宿主「说话」的全部通道,零日志)。
//!
//! 0.3.0 拆自原 log_plugin.rs:宿主不携带任何日志类型、不内置日志插件 ——
//! 它想说的话全部是**结构化事件**:
//! - `ePlugUp` / `ePlugUp.<名>`:插件上线(载荷 [`crate::service::PlugNotice`] / 版本串)
//! - `ePlugDown` / `ePlugDown.<名>`:正常摘除(载荷同上;宿主整体 close 不发逐插件事件,防事件风暴)
//! - `ePlugQDown.<名>`:熔断检疫定向广播(worker 自发;Q=quarantine,无载荷)
//! - `eSrvChg` / `eSrvChg.<名>`:服务目录改版(载荷同上)
//!
//! 运维诊断文本(邮箱溢出/panic 累计/close 超时)只走 `stderr`,不进总线、不定义任何类型。
//! 三族旁系(`ePlugDown` / `ePlugDown.<名>` / `ePlugQDown.<名>`)语义各别,严禁合并。
//!
//! 业务日志与宿主无关:谁想记日志谁自己 `ctx.put` 自己的载荷(业务链上用
//! `ek-data` 的 `LogData` 到 `"eLog"` 键),core 全程不在场。

/// 插件上线固定键(载荷 [`crate::service::PlugNotice`])。
pub const EVENT_PLUG_UP: &str = "ePlugUp";
/// 插件上线定向键(载荷:版本串)。
pub const EVENT_PLUG_UP_PREFIX: &str = "ePlugUp.";
/// 插件正常摘除固定键(载荷 [`crate::service::PlugNotice`])。
pub const EVENT_PLUG_DOWN: &str = "ePlugDown";
/// 插件正常摘除定向键(载荷:版本串)。正常摘除才用;宿主整体 close 不发。
pub const EVENT_PLUG_DOWN_EVENT_PREFIX: &str = "ePlugDown.";
/// 熔断检疫定向广播键(worker 自发;Q=quarantine,无载荷)。
pub const EVENT_PLUG_DOWN_PREFIX: &str = "ePlugQDown.";
/// 服务目录改版固定键(载荷 [`crate::service::PlugNotice`])。
pub const EVENT_SRV_CHG: &str = "eSrvChg";
/// 服务目录改版定向键(载荷:版本串)。
pub const EVENT_SRV_CHG_PREFIX: &str = "eSrvChg.";

#[cfg(test)]
mod tests {
    use super::*;

    /// 固定键不带点(可用于终寻),定向键以点结尾(组合面);三族旁系互异。
    #[test]
    fn lifecycle_keys_shape() {
        assert!(!EVENT_PLUG_UP.ends_with('.'));
        assert!(EVENT_PLUG_UP_PREFIX.ends_with('.'));
        assert!(!EVENT_PLUG_DOWN.ends_with('.'));
        assert!(EVENT_PLUG_DOWN_EVENT_PREFIX.ends_with('.'));
        assert!(EVENT_PLUG_DOWN_PREFIX.ends_with('.'));
        assert_ne!(EVENT_PLUG_DOWN_EVENT_PREFIX, EVENT_PLUG_DOWN_PREFIX);
        assert!(!EVENT_SRV_CHG.ends_with('.'));
        assert!(EVENT_SRV_CHG_PREFIX.ends_with('.'));
        assert!(EVENT_SRV_CHG.starts_with("eSrvChg"));
        assert!(EVENT_PLUG_UP.starts_with("ePlugUp"));
        assert!(EVENT_PLUG_DOWN.starts_with("ePlugDown"));
        assert!(EVENT_PLUG_DOWN_PREFIX.starts_with("ePlugQDown."));
    }
}