Adapt reaction-plugin to remoc

This commit is contained in:
ppom 2025-10-01 12:00:00 +02:00
commit 47cbf79b5f
No known key found for this signature in database
5 changed files with 156 additions and 205 deletions

230
Cargo.lock generated
View file

@ -191,6 +191,12 @@ version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.10.1"
@ -230,7 +236,7 @@ dependencies = [
"num-traits",
"serde",
"wasm-bindgen",
"windows-link 0.1.1",
"windows-link",
]
[[package]]
@ -699,16 +705,6 @@ version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libloading"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
dependencies = [
"cfg-if",
"windows-link 0.2.0",
]
[[package]]
name = "linux-raw-sys"
version = "0.9.4"
@ -905,6 +901,15 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "postbag"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02aa900208f326b4fa5d7943ede192c1265a1519e7132aa6760e3440a1f4ceb0"
dependencies = [
"serde",
]
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@ -944,15 +949,6 @@ dependencies = [
"termtree",
]
[[package]]
name = "proc-macro-crate"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
@ -984,8 +980,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
]
[[package]]
@ -995,7 +1001,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
@ -1007,6 +1023,15 @@ dependencies = [
"getrandom 0.2.16",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.3",
]
[[package]]
name = "reaction"
version = "2.2.1"
@ -1019,17 +1044,15 @@ dependencies = [
"clap_mangen",
"futures",
"jrsonnet-evaluator",
"libloading",
"nix",
"num_cpus",
"predicates",
"rand",
"rand 0.8.5",
"reaction-plugin",
"regex",
"serde",
"remoc",
"serde_json",
"serde_yaml",
"stabby",
"tempfile",
"thiserror",
"tokio",
@ -1042,7 +1065,8 @@ dependencies = [
name = "reaction-plugin"
version = "0.1.0"
dependencies = [
"stabby",
"remoc",
"serde",
]
[[package]]
@ -1083,6 +1107,36 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "remoc"
version = "0.18.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0491961ac4bc1ac4191743aa58a2ce778f4725693d29743fae957b2cf45f77f0"
dependencies = [
"byteorder",
"bytes",
"futures",
"postbag",
"rand 0.9.2",
"remoc_macro",
"serde",
"tokio",
"tokio-util",
"tracing",
"uuid",
]
[[package]]
name = "remoc_macro"
version = "0.18.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89479d9d87f65ef573faf0167dd0a9f40d3a63fd95e7a2935d662fa57dbc30d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "roff"
version = "0.2.2"
@ -1101,15 +1155,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "1.0.7"
@ -1150,12 +1195,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
version = "1.0.227"
@ -1211,12 +1250,6 @@ dependencies = [
"unsafe-libyaml",
]
[[package]]
name = "sha2-const-stable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9"
[[package]]
name = "sharded-slab"
version = "0.1.7"
@ -1266,42 +1299,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "stabby"
version = "72.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976399a0c48ea769ef7f5dc303bb88240ab8d84008647a6b2303eced3dab3945"
dependencies = [
"libloading",
"rustversion",
"stabby-abi",
]
[[package]]
name = "stabby-abi"
version = "72.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b54832a9a1f92a0e55e74a5c0332744426edc515bb3fbad82f10b874a87f0d"
dependencies = [
"rustc_version",
"rustversion",
"sha2-const-stable",
"stabby-macros",
]
[[package]]
name = "stabby-macros"
version = "72.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a768b1e51e4dbfa4fa52ae5c01241c0a41e2938fdffbb84add0c8238092f9091"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"rand",
"syn 1.0.109",
]
[[package]]
name = "strsim"
version = "0.11.1"
@ -1434,36 +1431,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "toml_datetime"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.23.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b"
dependencies = [
"indexmap",
"toml_datetime",
"toml_parser",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
dependencies = [
"winnow",
]
[[package]]
name = "tracing"
version = "0.1.41"
@ -1557,6 +1524,18 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
dependencies = [
"getrandom 0.3.3",
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
name = "valuable"
version = "0.1.1"
@ -1694,7 +1673,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link 0.1.1",
"windows-link",
"windows-result",
"windows-strings",
]
@ -1727,19 +1706,13 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-result"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link 0.1.1",
"windows-link",
]
[[package]]
@ -1748,7 +1721,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link 0.1.1",
"windows-link",
]
[[package]]
@ -1833,15 +1806,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"

View file

@ -42,7 +42,6 @@ num_cpus = "1.16.0"
# Regex matching
regex = "1.10.4"
# Configuration languages, ser/deserialisation
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
serde_yaml = "0.9.34"
jrsonnet-evaluator = "0.4.2"
@ -56,8 +55,7 @@ tokio-util = { version = "0.7.12", features = ["codec"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
# Reaction plugin system
libloading = "0.8.9"
stabby = { workspace = true, features = ["libloading"] }
remoc = { workspace = true }
reaction-plugin = { path = "reaction-plugin" }
[build-dependencies]
@ -77,4 +75,5 @@ predicates = "3.1.3"
[workspace]
[workspace.dependencies]
stabby = { version = "72.1.1" }
remoc = { version = "0.18.3" }
serde = { version = "1.0.203", features = ["derive"] }

View file

@ -4,4 +4,5 @@ version = "0.1.0"
edition = "2024"
[dependencies]
stabby.workspace = true
remoc.workspace = true
serde.workspace = true

View file

@ -1,92 +1,94 @@
/// This crate permits to define a stable ABI between reaction's core and plugins.
/// This crate defines the API between reaction's core and plugins.
///
/// It uses [`stabby`], that rewrites essential std types as stable repr("C") types,
/// and permits to check a lof of safeness related issues at compile time and at runtime, when
/// loading a library.
/// It's based on [`remoc`], which permits to multiplex channels and remote objects/functions/trait
/// calls over a single transport channel.
///
/// To implement a plugin, one has to provide an implementation of [`PluginInfo`], that provides
/// the entrypoint for a plugin.
/// It permits to define 0 to n (stream, filter, action) custom types.
///
/// It must also export a function that returns an impl of the trait:
/// ```rust
/// #[stabby::export(checked)]
/// extern "C" fn reaction_plugin() -> BoxedPluginInfo {
/// ...
/// }
/// ```
use stabby::{
boxed::Box, future::DynFuture, option::Option, result::Result, string::String, vec::Vec,
};
mod value;
pub use value::Value;
use remoc::{rch, rtc};
use serde::{Deserialize, Serialize};
/// This is the only trait that **must** be implemented by a plugin.
/// It provides lists of stream, filter and action types implemented by a dynamic plugin.
#[stabby::stabby(checked)]
#[rtc::remote]
pub trait PluginInfo {
/// Return all stream types that should be made available to reaction users
extern "C" fn stream_impls(&self) -> Vec<String>;
/// Return one instance of a given type.
extern "C" fn stream_impl(
async fn stream_impls(&self) -> RemoteResult<Vec<String>>;
/// Return one stream of a given type if it exists
async fn stream_impl(
&mut self,
stream_name: String,
stream_type: String,
config: Value,
) -> Result<BoxedStreamImpl, String>;
) -> RemoteResult<Result<StreamImpl, String>>;
// /// Return all filter types that should be made available to reaction users
// extern "C" fn filter_impls(&self) -> Vec<String>;
// /// Return one instance of a given type.
// extern "C" fn filter_impl(
// async fn filter_impls(&self) -> RemoteResult<Vec<String>>;
// /// Return one stream of a given type if it exists
// async fn filter_impl(
// &mut self,
// stream_name: String,
// filter_name: String,
// filter_type: String,
// stream_type: String,
// config: Value,
// ) -> Result<BoxedFilterImpl, String>;
// ) -> RemoteResult<Result<FilterImpl, String>>;
/// Return all action types that should be made available to reaction users
extern "C" fn action_impls(&self) -> Vec<String>;
async fn action_impls(&self) -> RemoteResult<Vec<String>>;
/// Return one instance of a given type.
extern "C" fn action_impl(
async fn action_impl(
&mut self,
stream_name: String,
filter_name: String,
action_name: String,
action_type: String,
config: Value,
) -> Result<BoxedActionImpl, String>;
) -> RemoteResult<Result<ActionImpl, String>>;
/// Notify the plugin that setup is finished, permitting a last occasion to report an error
/// (For example if a stream wants a companion action but it hasn't been initialized)
extern "C" fn finish_setup(&mut self) -> Result<(), String>;
async fn finish_setup(&mut self) -> RemoteResult<Result<(), String>>;
}
pub type BoxedPluginInfo = stabby::dynptr!(Box<dyn PluginInfo>);
pub type BoxedStreamImpl = stabby::dynptr!(Box<dyn StreamImpl + Sync + Send>);
// pub type BoxedFilterImpl = stabby::dynptr!(Box<dyn FilterImpl>);
pub type BoxedActionImpl = stabby::dynptr!(Box<dyn ActionImpl + Sync + Send>);
pub type RemoteResult<T> = Result<T, rtc::CallError>;
#[stabby::stabby(checked)]
pub trait StreamImpl {
extern "C" fn start<'a>(&'a mut self) -> DynFuture<'a, Result<(), String>>;
extern "C" fn next<'a>(&'a mut self) -> DynFuture<'a, Result<Option<String>, String>>;
extern "C" fn close<'a>(&'a mut self) -> DynFuture<'a, Result<(), String>>;
/// Represents a configuration value.
/// This is not meant as an efficient type, but as a very flexible one.
#[derive(Serialize, Deserialize)]
pub enum Value {
Null,
Bool(bool),
Integer(i64),
Float(f64),
String(String),
Array(Vec<Value>),
Object(Vec<(String, Value)>),
}
// #[stabby::stabby(checked)]
// pub trait FilterImpl {
// extern "C" fn matches<'a>(&'a mut self, line: String) -> DynFuture<'a, bool>;
// extern "C" fn close<'a>(&'a mut self) -> DynFuture<'a, Result<(), String>>;
#[derive(Serialize, Deserialize)]
pub struct StreamImpl {
pub stream: rch::lr::Receiver<Result<String, String>>,
}
// #[derive(Serialize, Deserialize)]
// pub struct FilterImpl {
// pub stream: rch::lr::Sender<Exec>,
// }
#[stabby::stabby(checked)]
pub trait ActionImpl {
extern "C" fn exec<'a>(
&'a mut self,
match_: Vec<String>,
) -> DynFuture<'a, Result<Option<Vec<u8>>, String>>;
extern "C" fn close<'a>(&'a mut self) -> DynFuture<'a, Result<(), String>>;
// #[derive(Serialize, Deserialize)]
// pub struct Match {
// pub match_: String,
// pub result: rch::oneshot::Sender<bool>,
// }
#[derive(Serialize, Deserialize)]
pub struct ActionImpl {
pub stream: rch::lr::Sender<Exec>,
}
#[derive(Serialize, Deserialize)]
pub struct Exec {
pub match_: Vec<String>,
pub result: rch::oneshot::Sender<String>,
}

View file

@ -1,15 +0,0 @@
use stabby::{string::String, tuple::Tuple2, vec::Vec};
/// Represents a configuration value.
/// This is not meant as an efficient type, but as a very flexible one.
#[stabby::stabby]
#[repr(C, u8)]
pub enum Value {
Null,
Bool(bool),
Integer(i64),
Float(f64),
String(String),
Array(Vec<Value>),
Object(Vec<Tuple2<String, Value>>),
}