Crate kokoro_core
source ·Expand description
Kokoro
Dynamic publish-subscribe pattern framework.
Support for dynamic plug-ins and AOP
Not yet stable, do not use in production !!
§Simple publish/subscribe
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);
}
§Plug-in system with dynamic capabilities
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(())
}
Plugin (Dynamic link library)
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
§todo list
-
kokoro-default-impl
-
kokoro-plugin-impl
-
kokoro-thread-impl
-
kokoro-service-impl (AOP Support)
-
-
kokoro-dynamic-plugin-impl
- plugin config api
-
loader
for dynamically and schematically loading plugins. -
logger
for uniform output logging of plugins. -
k-onfig
is used to hint configuration schema. -
Satori (EventType only)
for instant messaging or chatbots
Modules§
- The heart of Kokoro is the Context
- Some useful implementations Abstract what can be disposed
- Traits of the event to be publish
- A schedule that each node will have
- Subscribers, which are executed when a message is received