#pub-sub #event-bus #aop #pubsub #kokoro

kokoro-core

动态发布/订阅模式框架

4个版本

0.0.6 2024年2月28日
0.0.5 2024年2月19日

#7 in #aop

每月37次下载
4 crates 中使用

Apache-2.0/MIT

27KB
598

Kokoro

docs.rs Crates.io Version Crates.io License

动态发布/订阅模式框架。

支持动态插件和AOP

尚未稳定,请勿在生产环境中使用 !!


简单发布/订阅

use std::fmt::Display;
use kokoro::prelude::*;
fn main() {
    let ctx = channel_ctx();
    // Register a subscriber
    ctx.subscribe(sub_print);
    // Create a publisher
    let _ = ctx.spawn(|ctx, s| {
        // s is a signal that is true when the thread should be terminated
        while !s.is() {
            // Publish the event:Print
            ctx.publish(Print(&"Hello World"));
            std::thread::sleep(std::time::Duration::from_secs(1));
        }
    });
    ctx.run();
    /* Typically, the output will be :
     *  Hello World
     *  ...
    */
}

#[derive(Event)]
// This is a event:Print
struct Print(&'static dyn Display);

// This is a subscriber who subscribes to the event:Print
fn sub_print(print: &Print) {
    println!("{}", print.0);
}

具有动态功能的插件系统

APP

use kokoro::prelude::*;

fn main() -> Result<()> {
    let ctx = channel_ctx();
    // let dyp = DynamicPlugin::from_path("path to Plugin (Dynamic link library)"); // Also can do it
    // let dyp = DynamicPlugin::try_from(unsafe { libloading::Library::new("path to Plugin (Dynamic link library)") }); // Also can do it
    let dyp = "path to Plugin (Dynamic link library)"; // String or Library or DynamicPlugin
    let config = toml::toml! {
        hello = "I am plugin"
    };
    ctx.plugin_dynamic(dyp, Some(content.into()))?;
    ctx.publish(PhantomEvent);
    ctx.run();
    /* Typically, the output will be :
     *  I am plugin plugin-example
    */
    Ok(())
}

插件(动态链接库)

use kokoro::prelude::*;
use kokoro::dynamic_plugin::toml::Value;
use serde::Deserialize;

#[derive(DynamicPlugin, Deserialize)]
struct MyPlugin {
    hello: String,
}

impl Plugin for MyPlugin {
    type MODE = MPSC;
    const NAME: &'static str = "plugin-example";
    fn apply(ctx: Context<Self, MPSC>) -> Result<()> {
        ctx.subscribe(sub);
        Ok(())
    }
}

impl Create for MyPlugin {
    fn create(config: Option<Value>) -> Result<Self> {
        if let Some(config) = config {
            let config = MyPlugin::deserialize(config)?;
            Ok(config)
        } else {
            Err(anyhow!("Required Config"))
        }
    }
}

fn sub(ctx: &Context<MyPlugin, MPSC>) {
    println!(
        "{} {}",
        ctx.hello,
        MyPlugin::NAME
    );
}

星历

Star History Chart

待办事项列表

  • kokoro-default-impl
    • kokoro-plugin-impl
    • kokoro-thread-impl
    • kokoro-服务-实现 (AOP 支持)
  • kokoro-dynamic-plugin-impl
  • 插件配置API
  • loader 用于动态和结构化加载插件。
  • logger 用于插件统一输出日志。
  • k-onfig 用于提示配置模式。
  • Satori (EventType only) 用于即时消息或聊天机器人

依赖关系

~2.2–8.5MB
~48K SLoC