From 0164dd821df192816270de7778cc8d440cc13531 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 9 Oct 2023 17:28:30 +0200 Subject: [PATCH 001/106] made runtime state fields private --- plugins/example-plugin/src/lib.rs | 2 +- plugins/zenoh-plugin-rest/src/lib.rs | 4 +- .../zenoh-plugin-storage-manager/src/lib.rs | 5 ++- zenoh/src/info.rs | 2 +- zenoh/src/liveliness.rs | 7 +++- zenoh/src/net/routing/network.rs | 2 +- zenoh/src/net/routing/resource.rs | 1 + zenoh/src/net/routing/router.rs | 1 + zenoh/src/net/runtime/mod.rs | 40 ++++++++++++++----- zenoh/src/session.rs | 17 ++++---- zenohd/src/main.rs | 2 +- 11 files changed, 56 insertions(+), 27 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 5e82170376..18dbedb2aa 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -47,7 +47,7 @@ impl Plugin for ExamplePlugin { // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { - let config = runtime.config.lock(); + let config = runtime.config().lock(); let self_cfg = config.plugin(name).unwrap().as_object().unwrap(); // get the plugin's config details from self_cfg Map (here the "storage-selector" property) let selector: KeyExpr = match self_cfg.get("storage-selector") { diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 6cea5f8e0c..6c908bf92c 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -225,7 +225,7 @@ impl Plugin for RestPlugin { let _ = env_logger::try_init(); log::debug!("REST plugin {}", LONG_VERSION.as_str()); - let runtime_conf = runtime.config.lock(); + let runtime_conf = runtime.config().lock(); let plugin_conf = runtime_conf .plugin(name) .ok_or_else(|| zerror!("Plugin `{}`: missing config", name))?; @@ -476,7 +476,7 @@ pub async fn run(runtime: Runtime, conf: Config) -> ZResult<()> { // But cannot be done twice in case of static link. let _ = env_logger::try_init(); - let zid = runtime.zid.to_string(); + let zid = runtime.zid().to_string(); let session = zenoh::init(runtime).res().await.unwrap(); let mut app = Server::with_state((Arc::new(session), zid)); diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index e9d9f6594b..0c4d4778c2 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -65,7 +65,7 @@ impl Plugin for StoragesPlugin { std::mem::drop(env_logger::try_init()); log::debug!("StorageManager plugin {}", LONG_VERSION.as_str()); let config = - { PluginConfig::try_from((name, runtime.config.lock().plugin(name).unwrap())) }?; + { PluginConfig::try_from((name, runtime.config().lock().plugin(name).unwrap())) }?; Ok(Box::new(StorageRuntime::from(StorageRuntimeInner::new( runtime.clone(), config, @@ -85,7 +85,8 @@ impl StorageRuntimeInner { fn status_key(&self) -> String { format!( "@/router/{}/status/plugins/{}", - &self.runtime.zid, &self.name + &self.runtime.zid(), + &self.name ) } fn new(runtime: Runtime, config: PluginConfig) -> ZResult { diff --git a/zenoh/src/info.rs b/zenoh/src/info.rs index b8b3d0bd88..5ab1cf4c3e 100644 --- a/zenoh/src/info.rs +++ b/zenoh/src/info.rs @@ -41,7 +41,7 @@ impl<'a> Resolvable for ZidBuilder<'a> { impl<'a> SyncResolve for ZidBuilder<'a> { fn res_sync(self) -> Self::To { - self.session.runtime.zid + self.session.runtime.zid() } } diff --git a/zenoh/src/liveliness.rs b/zenoh/src/liveliness.rs index be39e3b7f6..6604d069e6 100644 --- a/zenoh/src/liveliness.rs +++ b/zenoh/src/liveliness.rs @@ -185,11 +185,14 @@ impl<'a> Liveliness<'a> { >>::Error: Into, { let key_expr = key_expr.try_into().map_err(Into::into); - let conf = self.session.runtime.config.lock(); + let timeout = { + let conf = self.session.runtime.config().lock(); + Duration::from_millis(unwrap_or_default!(conf.queries_default_timeout())) + }; LivelinessGetBuilder { session: &self.session, key_expr, - timeout: Duration::from_millis(unwrap_or_default!(conf.queries_default_timeout())), + timeout, handler: DefaultHandler, } } diff --git a/zenoh/src/net/routing/network.rs b/zenoh/src/net/routing/network.rs index 3af1e0a87c..34ef6e90f3 100644 --- a/zenoh/src/net/routing/network.rs +++ b/zenoh/src/net/routing/network.rs @@ -134,7 +134,7 @@ impl Network { log::debug!("{} Add node (self) {}", name, zid); let idx = graph.add_node(Node { zid, - whatami: Some(runtime.whatami), + whatami: Some(runtime.whatami()), locators: None, sn: 1, links: vec![], diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index e26a9217f3..2b60a301ea 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -363,6 +363,7 @@ impl Resource { } } + #[allow(dead_code)] pub fn print_tree(from: &Arc) -> String { let mut result = from.expr(); result.push('\n'); diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index dbf687ba79..5a2369f08c 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -140,6 +140,7 @@ impl Tables { &self.root_res } + #[allow(dead_code)] pub fn print(&self) -> String { Resource::print_tree(&self.root_res) } diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 92d369e998..c776e229d4 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -47,16 +47,16 @@ use zenoh_transport::{ }; pub struct RuntimeState { - pub zid: ZenohId, - pub whatami: WhatAmI, - pub metadata: serde_json::Value, - pub router: Arc, - pub config: Notifier, - pub manager: TransportManager, - pub transport_handlers: std::sync::RwLock>>, - pub(crate) locators: std::sync::RwLock>, - pub hlc: Option>, - pub(crate) stop_source: std::sync::RwLock>, + zid: ZenohId, + whatami: WhatAmI, + metadata: serde_json::Value, + router: Arc, + config: Notifier, + manager: TransportManager, + transport_handlers: std::sync::RwLock>>, + locators: std::sync::RwLock>, + hlc: Option>, + stop_source: std::sync::RwLock>, } #[derive(Clone)] @@ -213,6 +213,26 @@ impl Runtime { .as_ref() .map(|source| async_std::task::spawn(future.timeout_at(source.token()))) } + + pub(crate) fn router(&self) -> Arc { + self.router.clone() + } + + pub fn config(&self) -> &Notifier { + &self.config + } + + pub fn hlc(&self) -> Option<&HLC> { + self.hlc.as_ref().map(Arc::as_ref) + } + + pub fn zid(&self) -> ZenohId { + self.zid + } + + pub fn whatami(&self) -> WhatAmI { + self.whatami + } } struct RuntimeTransportEventHandler { diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index 744f21965f..d83981ed53 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -333,7 +333,7 @@ impl Session { aggregated_publishers: Vec, ) -> impl Resolve { ResolveClosure::new(move || { - let router = runtime.router.clone(); + let router = runtime.router(); let state = Arc::new(RwLock::new(SessionState::new( aggregated_subscribers, aggregated_publishers, @@ -426,7 +426,7 @@ impl Session { } pub fn hlc(&self) -> Option<&HLC> { - self.runtime.hlc.as_ref().map(Arc::as_ref) + self.runtime.hlc() } /// Close the zenoh [`Session`](Session). @@ -491,7 +491,7 @@ impl Session { /// # }) /// ``` pub fn config(&self) -> &Notifier { - &self.runtime.config + &self.runtime.config() } /// Get informations about the zenoh [`Session`](Session). @@ -780,7 +780,10 @@ impl Session { >>::Error: Into, { let selector = selector.try_into().map_err(Into::into); - let conf = self.runtime.config.lock(); + let timeout = { + let conf = self.runtime.config().lock(); + Duration::from_millis(unwrap_or_default!(conf.queries_default_timeout())) + }; GetBuilder { session: self, selector, @@ -788,7 +791,7 @@ impl Session { target: QueryTarget::default(), consolidation: QueryConsolidation::default(), destination: Locality::default(), - timeout: Duration::from_millis(unwrap_or_default!(conf.queries_default_timeout())), + timeout, value: None, handler: DefaultHandler, } @@ -1590,7 +1593,7 @@ impl Session { }; task::spawn({ let state = self.state.clone(); - let zid = self.runtime.zid; + let zid = self.runtime.zid(); async move { task::sleep(timeout).await; let mut state = zwrite!(state); @@ -1731,7 +1734,7 @@ impl Session { let parameters = parameters.to_owned(); - let zid = self.runtime.zid; // @TODO build/use prebuilt specific zid + let zid = self.runtime.zid(); // @TODO build/use prebuilt specific zid let query = Query { inner: Arc::new(QueryInner { diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 2b23604c83..5c9396e3d8 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -137,7 +137,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na log::info!("Finished loading plugins"); { - let mut config_guard = runtime.config.lock(); + let mut config_guard = runtime.config().lock(); for (name, (_, plugin)) in plugins.running_plugins() { let hook = plugin.config_checker(); config_guard.add_plugin_validator(name, hook) From e0dbcf561f6d3b379476237cb532f2b5e21d1126 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 10 Oct 2023 08:44:04 +0000 Subject: [PATCH 002/106] RuntimeState private --- zenoh/src/net/runtime/adminspace.rs | 30 ++++++++++---------- zenoh/src/net/runtime/mod.rs | 41 +++++++++++---------------- zenoh/src/net/runtime/orchestrator.rs | 24 +++++++++------- 3 files changed, 45 insertions(+), 50 deletions(-) diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 0eb099a098..92ab103bb6 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -66,8 +66,8 @@ enum PluginDiff { impl AdminSpace { pub async fn start(runtime: &Runtime, plugins_mgr: plugins::PluginsManager, version: String) { - let zid_str = runtime.zid.to_string(); - let metadata = runtime.metadata.clone(); + let zid_str = runtime.state.zid.to_string(); + let metadata = runtime.state.metadata.clone(); let root_key: OwnedKeyExpr = format!("@/router/{zid_str}").try_into().unwrap(); let mut handlers: HashMap<_, Handler> = HashMap::new(); @@ -121,14 +121,14 @@ impl AdminSpace { metadata, }); let admin = Arc::new(AdminSpace { - zid: runtime.zid, + zid: runtime.zid(), primitives: Mutex::new(None), mappings: Mutex::new(HashMap::new()), handlers, context, }); - let cfg_rx = admin.context.runtime.config.subscribe(); + let cfg_rx = admin.context.runtime.state.config.subscribe(); task::spawn({ let admin = admin.clone(); async move { @@ -139,7 +139,7 @@ impl AdminSpace { } let requested_plugins = { - let cfg_guard = admin.context.runtime.config.lock(); + let cfg_guard = admin.context.runtime.state.config.lock(); cfg_guard.plugins().load_requests().collect::>() }; let mut diffs = Vec::new(); @@ -195,7 +195,7 @@ impl AdminSpace { Ok(Some((path, plugin))) => { active_plugins.insert(name.into(), path.into()); let mut cfg_guard = - admin.context.runtime.config.lock(); + admin.context.runtime.state.config.lock(); cfg_guard.add_plugin_validator( name, plugin.config_checker(), @@ -221,7 +221,7 @@ impl AdminSpace { } }); - let primitives = runtime.router.new_primitives(admin.clone()); + let primitives = runtime.state.router.new_primitives(admin.clone()); zlock!(admin.primitives).replace(primitives.clone()); primitives.send_declare(Declare { @@ -283,7 +283,7 @@ impl Primitives for AdminSpace { fn send_push(&self, msg: Push) { trace!("recv Push {:?}", msg); { - let conf = self.context.runtime.config.lock(); + let conf = self.context.runtime.state.config.lock(); if !conf.adminspace.permissions().write { log::error!( "Received PUT on '{}' but adminspace.permissions.write=false in configuration", @@ -307,7 +307,7 @@ impl Primitives for AdminSpace { key, json ); - if let Err(e) = (&self.context.runtime.config).insert_json5(key, json) { + if let Err(e) = (&self.context.runtime.state.config).insert_json5(key, json) { error!( "Error inserting conf value /@/router/{}/config/{} : {} - {}", &self.context.zid_str, key, json, e @@ -325,7 +325,7 @@ impl Primitives for AdminSpace { &self.context.zid_str, key ); - if let Err(e) = self.context.runtime.config.remove(key) { + if let Err(e) = self.context.runtime.state.config.remove(key) { log::error!("Error deleting conf value {} : {}", msg.wire_expr, e) } } @@ -338,7 +338,7 @@ impl Primitives for AdminSpace { if let RequestBody::Query(query) = msg.payload { let primitives = zlock!(self.primitives).as_ref().unwrap().clone(); { - let conf = self.context.runtime.config.lock(); + let conf = self.context.runtime.state.config.lock(); if !conf.adminspace.permissions().read { log::error!( "Received GET on '{}' but adminspace.permissions.read=false in configuration", @@ -528,7 +528,7 @@ fn routers_linkstate_data(context: &AdminContext, query: Query) { .try_into() .unwrap(); - let tables = zread!(context.runtime.router.tables.tables); + let tables = zread!(context.runtime.state.router.tables.tables); if let Err(e) = query .reply(Ok(Sample::new( @@ -555,7 +555,7 @@ fn peers_linkstate_data(context: &AdminContext, query: Query) { .try_into() .unwrap(); - let tables = zread!(context.runtime.router.tables.tables); + let tables = zread!(context.runtime.state.router.tables.tables); if let Err(e) = query .reply(Ok(Sample::new( @@ -578,7 +578,7 @@ fn peers_linkstate_data(context: &AdminContext, query: Query) { } fn subscribers_data(context: &AdminContext, query: Query) { - let tables = zread!(context.runtime.router.tables.tables); + let tables = zread!(context.runtime.state.router.tables.tables); for sub in tables.router_subs.iter() { let key = KeyExpr::try_from(format!( "@/router/{}/subscriber/{}", @@ -595,7 +595,7 @@ fn subscribers_data(context: &AdminContext, query: Query) { } fn queryables_data(context: &AdminContext, query: Query) { - let tables = zread!(context.runtime.router.tables.tables); + let tables = zread!(context.runtime.state.router.tables.tables); for qabl in tables.router_qabls.iter() { let key = KeyExpr::try_from(format!( "@/router/{}/queryable/{}", diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index c776e229d4..fbfe24aadc 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -46,7 +46,7 @@ use zenoh_transport::{ TransportMulticastEventHandler, TransportPeer, TransportPeerEventHandler, TransportUnicast, }; -pub struct RuntimeState { +struct RuntimeState { zid: ZenohId, whatami: WhatAmI, metadata: serde_json::Value, @@ -64,14 +64,6 @@ pub struct Runtime { state: Arc, } -impl std::ops::Deref for Runtime { - type Target = RuntimeState; - - fn deref(&self) -> &RuntimeState { - self.state.deref() - } -} - impl Runtime { pub async fn new(config: Config) -> ZResult { let mut runtime = Runtime::init(config).await?; @@ -150,7 +142,7 @@ impl Runtime { }), }; *handler.runtime.write().unwrap() = Some(runtime.clone()); - get_mut_unchecked(&mut runtime.router.clone()).init_link_state( + get_mut_unchecked(&mut runtime.state.router.clone()).init_link_state( runtime.clone(), router_link_state, peer_link_state, @@ -180,7 +172,7 @@ impl Runtime { #[inline(always)] pub fn manager(&self) -> &TransportManager { - &self.manager + &self.state.manager } pub fn new_handler(&self, handler: Arc) { @@ -189,17 +181,17 @@ impl Runtime { pub async fn close(&self) -> ZResult<()> { log::trace!("Runtime::close())"); - drop(self.stop_source.write().unwrap().take()); + drop(self.state.stop_source.write().unwrap().take()); self.manager().close().await; Ok(()) } pub fn new_timestamp(&self) -> Option { - self.hlc.as_ref().map(|hlc| hlc.new_timestamp()) + self.state.hlc.as_ref().map(|hlc| hlc.new_timestamp()) } pub fn get_locators(&self) -> Vec { - self.locators.read().unwrap().clone() + self.state.locators.read().unwrap().clone() } pub(crate) fn spawn(&self, future: F) -> Option>> @@ -207,7 +199,7 @@ impl Runtime { F: Future + Send + 'static, T: Send + 'static, { - self.stop_source + self.state.stop_source .read() .unwrap() .as_ref() @@ -215,23 +207,23 @@ impl Runtime { } pub(crate) fn router(&self) -> Arc { - self.router.clone() + self.state.router.clone() } pub fn config(&self) -> &Notifier { - &self.config + &self.state.config } pub fn hlc(&self) -> Option<&HLC> { - self.hlc.as_ref().map(Arc::as_ref) + self.state.hlc.as_ref().map(Arc::as_ref) } pub fn zid(&self) -> ZenohId { - self.zid + self.state.zid } pub fn whatami(&self) -> WhatAmI { - self.whatami + self.state.whatami } } @@ -248,7 +240,7 @@ impl TransportEventHandler for RuntimeTransportEventHandler { match zread!(self.runtime).as_ref() { Some(runtime) => { let slave_handlers: Vec> = - zread!(runtime.transport_handlers) + zread!(runtime.state.transport_handlers) .iter() .filter_map(|handler| { handler.new_unicast(peer.clone(), transport.clone()).ok() @@ -257,7 +249,7 @@ impl TransportEventHandler for RuntimeTransportEventHandler { Ok(Arc::new(RuntimeSession { runtime: runtime.clone(), endpoint: std::sync::RwLock::new(None), - main_handler: runtime.router.new_transport_unicast(transport).unwrap(), + main_handler: runtime.state.router.new_transport_unicast(transport).unwrap(), slave_handlers, })) } @@ -272,11 +264,11 @@ impl TransportEventHandler for RuntimeTransportEventHandler { match zread!(self.runtime).as_ref() { Some(runtime) => { let slave_handlers: Vec> = - zread!(runtime.transport_handlers) + zread!(runtime.state.transport_handlers) .iter() .filter_map(|handler| handler.new_multicast(transport.clone()).ok()) .collect(); - runtime.router.new_transport_multicast(transport.clone())?; + runtime.state.router.new_transport_multicast(transport.clone())?; Ok(Arc::new(RuntimeMuticastGroup { runtime: runtime.clone(), transport, @@ -365,6 +357,7 @@ impl TransportMulticastEventHandler for RuntimeMuticastGroup { Ok(Arc::new(RuntimeMuticastSession { main_handler: self .runtime + .state .router .new_peer_multicast(self.transport.clone(), peer)?, slave_handlers, diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index ccd2e68f6a..d0b420306d 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -47,7 +47,7 @@ pub enum Loop { impl Runtime { pub(crate) async fn start(&mut self) -> ZResult<()> { - match self.whatami { + match self.whatami() { WhatAmI::Client => self.start_client().await, WhatAmI::Peer => self.start_peer().await, WhatAmI::Router => self.start_router().await, @@ -56,7 +56,7 @@ impl Runtime { async fn start_client(&self) -> ZResult<()> { let (peers, scouting, addr, ifaces, timeout) = { - let guard = self.config.lock(); + let guard = self.state.config.lock(); ( guard.connect().endpoints().clone(), unwrap_or_default!(guard.scouting().multicast().enabled()), @@ -110,12 +110,13 @@ impl Runtime { async fn start_peer(&self) -> ZResult<()> { let (listeners, peers, scouting, listen, autoconnect, addr, ifaces, delay) = { - let guard = &self.config.lock(); + let guard = &self.state.config.lock(); let listeners = if guard.listen().endpoints().is_empty() { let endpoint: EndPoint = PEER_DEFAULT_LISTENER.parse().unwrap(); let protocol = endpoint.protocol(); let mut listeners = vec![]; if self + .state .manager .config .protocols @@ -155,12 +156,13 @@ impl Runtime { async fn start_router(&self) -> ZResult<()> { let (listeners, peers, scouting, listen, autoconnect, addr, ifaces) = { - let guard = self.config.lock(); + let guard = self.state.config.lock(); let listeners = if guard.listen().endpoints().is_empty() { let endpoint: EndPoint = ROUTER_DEFAULT_LISTENER.parse().unwrap(); let protocol = endpoint.protocol(); let mut listeners = vec![]; if self + .state .manager .config .protocols @@ -241,10 +243,10 @@ impl Runtime { } pub(crate) async fn update_peers(&self) -> ZResult<()> { - let peers = { self.config.lock().connect().endpoints().clone() }; + let peers = { self.state.config.lock().connect().endpoints().clone() }; let tranports = self.manager().get_transports_unicast().await; - if self.whatami == WhatAmI::Client { + if self.state.whatami == WhatAmI::Client { for transport in tranports { let should_close = if let Ok(Some(orch_transport)) = transport.get_callback() { if let Some(orch_transport) = orch_transport @@ -301,7 +303,7 @@ impl Runtime { } } - let mut locators = self.locators.write().unwrap(); + let mut locators = self.state.locators.write().unwrap(); *locators = self.manager().get_locators(); for locator in &*locators { log::info!("Zenoh can be reached at: {}", locator); @@ -771,7 +773,7 @@ impl Runtime { if let Ok(msg) = res { log::trace!("Received {:?} from {}", msg.body, peer); if let ScoutingBody::Scout(Scout { what, .. }) = &msg.body { - if what.matches(self.whatami) { + if what.matches(self.whatami()) { let mut wbuf = vec![]; let mut writer = wbuf.writer(); let codec = Zenoh080::new(); @@ -779,7 +781,7 @@ impl Runtime { let zid = self.manager().zid(); let hello: ScoutingMessage = Hello { version: zenoh_protocol::VERSION, - whatami: self.whatami, + whatami: self.whatami(), zid, locators: self.get_locators(), } @@ -811,7 +813,7 @@ impl Runtime { } pub(super) fn closing_session(session: &RuntimeSession) { - match session.runtime.whatami { + match session.runtime.whatami() { WhatAmI::Client => { let runtime = session.runtime.clone(); session.runtime.spawn(async move { @@ -827,7 +829,7 @@ impl Runtime { } _ => { if let Some(endpoint) = &*zread!(session.endpoint) { - let peers = { session.runtime.config.lock().connect().endpoints().clone() }; + let peers = { session.runtime.state.config.lock().connect().endpoints().clone() }; if peers.contains(endpoint) { let endpoint = endpoint.clone(); let runtime = session.runtime.clone(); From 47daf4c6d387d7632a8a66ad058f5feacd73c267 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 10 Oct 2023 15:31:57 +0000 Subject: [PATCH 003/106] removing ValidationFunction unfinished --- zenoh/src/net/runtime/adminspace.rs | 22 +++++++++++++++++++--- zenoh/src/plugins/sealed.rs | 9 ++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 92ab103bb6..99b48367cd 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -192,13 +192,28 @@ impl AdminSpace { let name = &plugin.name; log::info!("Loaded plugin `{}` from {}", name, &path); match plugins_mgr.start(name, &admin.context.runtime) { - Ok(Some((path, plugin))) => { + Ok(Some((path, _))) => { active_plugins.insert(name.into(), path.into()); let mut cfg_guard = admin.context.runtime.state.config.lock(); + let validation_function = { + let name = name.clone(); + let admin = admin.clone(); + Arc::new(move |path: &_, old: &_, new: &_| { + let plugins_mgr = + zlock!(admin.context.plugins_mgr); + if let Some(plugin) = + plugins_mgr.plugin(name.as_str()) + { + plugin.config_checker(path, old, new) + } else { + Err("Plugin not found".into()) + } + }) + }; cfg_guard.add_plugin_validator( name, - plugin.config_checker(), + validation_function, ); log::info!( "Successfully started plugin `{}` from {}", @@ -307,7 +322,8 @@ impl Primitives for AdminSpace { key, json ); - if let Err(e) = (&self.context.runtime.state.config).insert_json5(key, json) { + if let Err(e) = (&self.context.runtime.state.config).insert_json5(key, json) + { error!( "Error inserting conf value /@/router/{}/config/{} : {} - {}", &self.context.zid_str, key, json, e diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 6caabca990..037aa50c83 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -45,8 +45,8 @@ impl Response { } } -pub trait RunningPluginTrait: Send + Sync + std::any::Any { - /// Returns a function that will be called when configuration relevant to the plugin is about to change. +pub trait RunningPluginTrait: Send + Sync { + /// Function that will be called when configuration relevant to the plugin is about to change. /// /// This function is called with 3 arguments: /// * `path`, the relative path from the plugin's configuration root to the changed value. @@ -58,7 +58,10 @@ pub trait RunningPluginTrait: Send + Sync + std::any::Any { /// Useful when the changes affect settings that aren't hot-configurable for your plugin. /// * `Ok(None)` indicates that the plugin has accepted the configuration change. /// * `Ok(Some(value))` indicates that the plugin would rather the new configuration be `value`. - fn config_checker(&self) -> ValidationFunction; + fn config_checker(&self, + path: &str, + current: &serde_json::Map, + new: &serde_json::Map) -> ZResult>>; /// Used to request your plugin's status for the administration space. fn adminspace_getter<'a>( &'a self, From b92007399e847addca81e5587a44df96221fccb2 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 11 Oct 2023 12:13:37 +0200 Subject: [PATCH 004/106] make validator function --- commons/zenoh-config/src/lib.rs | 10 ++++---- zenoh/src/net/runtime/adminspace.rs | 36 +++++++++++++++-------------- zenohd/src/main.rs | 8 ------- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index b0857f2caf..faaf362b95 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -46,11 +46,12 @@ use zenoh_protocol::{ use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; -pub type ValidationFunction = std::sync::Arc< +type ValidationFunction = std::sync::Arc< dyn Fn( - &str, - &serde_json::Map, - &serde_json::Map, + &str, // plugin name + &str, // `path`, the relative path from the plugin's configuration root to the changed value. + &serde_json::Map, // `current`, the current configuration of the plugin (from its root). + &serde_json::Map, // `new`, the proposed new configuration of the plugin. ) -> ZResult>> + Send + Sync, @@ -949,6 +950,7 @@ impl PluginsConfig { } let new_conf = if let Some(validator) = validator { match validator( + plugin, &key[("plugins/".len() + plugin.len())..], old_conf.as_object().unwrap(), new_conf.as_object().unwrap(), diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 99b48367cd..97a276ad6b 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -13,7 +13,7 @@ use super::routing::face::Face; use super::Runtime; use crate::key_expr::KeyExpr; -use crate::plugins::sealed as plugins; +use crate::plugins::sealed::{self as plugins, ValidationFunction}; use crate::prelude::sync::{Sample, SyncResolve}; use crate::queryable::Query; use crate::queryable::QueryInner; @@ -64,6 +64,18 @@ enum PluginDiff { Start(crate::config::PluginLoad), } +fn make_plugin_validator(admin: &Arc) -> ValidationFunction { + let admin = admin.clone(); + Arc::new(move |name: &_, path: &_, old: &_, new: &_| { + let plugins_mgr = zlock!(admin.context.plugins_mgr); + if let Some(plugin) = plugins_mgr.plugin(name) { + plugin.config_checker(path, old, new) + } else { + Err(format!("Plugin {name} not found").into()) + } + }) +} + impl AdminSpace { pub async fn start(runtime: &Runtime, plugins_mgr: plugins::PluginsManager, version: String) { let zid_str = runtime.state.zid.to_string(); @@ -128,6 +140,11 @@ impl AdminSpace { context, }); + let mut config_guard = admin.context.runtime.state.config.lock(); + for (name, (_, plugin)) in plugins.running_plugins() { + config_guard.add_plugin_validator(name, make_plugin_validator(&admin)) + } + let cfg_rx = admin.context.runtime.state.config.subscribe(); task::spawn({ let admin = admin.clone(); @@ -196,24 +213,9 @@ impl AdminSpace { active_plugins.insert(name.into(), path.into()); let mut cfg_guard = admin.context.runtime.state.config.lock(); - let validation_function = { - let name = name.clone(); - let admin = admin.clone(); - Arc::new(move |path: &_, old: &_, new: &_| { - let plugins_mgr = - zlock!(admin.context.plugins_mgr); - if let Some(plugin) = - plugins_mgr.plugin(name.as_str()) - { - plugin.config_checker(path, old, new) - } else { - Err("Plugin not found".into()) - } - }) - }; cfg_guard.add_plugin_validator( name, - validation_function, + make_plugin_validator(&admin), ); log::info!( "Successfully started plugin `{}` from {}", diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 5c9396e3d8..28df513a46 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -136,14 +136,6 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na } log::info!("Finished loading plugins"); - { - let mut config_guard = runtime.config().lock(); - for (name, (_, plugin)) in plugins.running_plugins() { - let hook = plugin.config_checker(); - config_guard.add_plugin_validator(name, hook) - } - } - AdminSpace::start(&runtime, plugins, LONG_VERSION.clone()).await; future::pending::<()>().await; From 735ae2b1e8dd31e451aac421c823572e30ebe0b8 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 11 Oct 2023 18:12:17 +0200 Subject: [PATCH 005/106] removed validation function --- commons/zenoh-config/src/lib.rs | 56 +++++++-------- plugins/example-plugin/src/lib.rs | 70 +++++++++---------- plugins/zenoh-plugin-rest/src/lib.rs | 11 +-- .../zenoh-plugin-storage-manager/src/lib.rs | 28 ++++---- zenoh/src/net/runtime/adminspace.rs | 24 +++---- zenoh/src/plugins/sealed.rs | 19 ++--- 6 files changed, 95 insertions(+), 113 deletions(-) diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index faaf362b95..19b2fea6ea 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -25,7 +25,7 @@ use serde_json::Value; use std::convert::TryFrom; // This is a false positive from the rust analyser use std::{ any::Any, - collections::{HashMap, HashSet}, + collections::HashSet, fmt, io::Read, marker::PhantomData, @@ -46,7 +46,7 @@ use zenoh_protocol::{ use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; -type ValidationFunction = std::sync::Arc< +pub type ValidationFunction = std::sync::Arc< dyn Fn( &str, // plugin name &str, // `path`, the relative path from the plugin's configuration root to the changed value. @@ -483,8 +483,8 @@ fn config_deser() { } impl Config { - pub fn add_plugin_validator(&mut self, name: impl Into, validator: ValidationFunction) { - self.plugins.validators.insert(name.into(), validator); + pub fn set_plugin_validator(&mut self, validator: ValidationFunction) { + self.plugins.validator = validator; } pub fn plugin(&self, name: &str) -> Option<&Value> { @@ -837,7 +837,7 @@ fn user_conf_validator(u: &UsrPwdConf) -> bool { #[derive(Clone)] pub struct PluginsConfig { values: Value, - validators: HashMap, + validator: ValidationFunction, } fn sift_privates(value: &mut serde_json::Value) { match value { @@ -903,11 +903,9 @@ impl PluginsConfig { Some(first_in_plugin) => first_in_plugin, None => { self.values.as_object_mut().unwrap().remove(plugin); - self.validators.remove(plugin); return Ok(()); } }; - let validator = self.validators.get(plugin); let (old_conf, mut new_conf) = match self.values.get_mut(plugin) { Some(plugin) => { let clone = plugin.clone(); @@ -948,18 +946,14 @@ impl PluginsConfig { } other => bail!("{} cannot be indexed", other), } - let new_conf = if let Some(validator) = validator { - match validator( - plugin, - &key[("plugins/".len() + plugin.len())..], - old_conf.as_object().unwrap(), - new_conf.as_object().unwrap(), - )? { - None => new_conf, - Some(new_conf) => Value::Object(new_conf), - } - } else { - new_conf + let new_conf = match (self.validator)( + plugin, + &key[("plugins/".len() + plugin.len())..], + old_conf.as_object().unwrap(), + new_conf.as_object().unwrap(), + )? { + None => new_conf, + Some(new_conf) => Value::Object(new_conf), }; *old_conf = new_conf; Ok(()) @@ -979,7 +973,7 @@ impl Default for PluginsConfig { fn default() -> Self { Self { values: Value::Object(Default::default()), - validators: Default::default(), + validator: Arc::new(|_, _, _, _| Ok(None)), } } } @@ -989,7 +983,7 @@ impl<'a> serde::Deserialize<'a> for PluginsConfig { D: serde::Deserializer<'a>, { Ok(PluginsConfig { - validators: Default::default(), + validator: Arc::new(|_, _, _, _| Ok(None)), values: serde::Deserialize::deserialize(deserializer)?, }) } @@ -1075,7 +1069,6 @@ impl validated_struct::ValidatedMap for PluginsConfig { validated_struct::InsertionError: From, { let (plugin, key) = validated_struct::split_once(key, '/'); - let validator = self.validators.get(plugin); let new_value: Value = serde::Deserialize::deserialize(deserializer)?; let value = self .values @@ -1084,16 +1077,15 @@ impl validated_struct::ValidatedMap for PluginsConfig { .entry(plugin) .or_insert(Value::Null); let mut new_value = value.clone().merge(key, new_value)?; - if let Some(validator) = validator { - match validator( - key, - value.as_object().unwrap(), - new_value.as_object().unwrap(), - ) { - Ok(Some(val)) => new_value = Value::Object(val), - Ok(None) => {} - Err(e) => return Err(format!("{e}").into()), - } + match (self.validator)( + plugin, + key, + value.as_object().unwrap(), + new_value.as_object().unwrap(), + ) { + Ok(Some(val)) => new_value = Value::Object(val), + Ok(None) => {} + Err(e) => return Err(format!("{e}").into()), } *value = new_value; Ok(()) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 18dbedb2aa..5c865ac8e8 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -21,7 +21,7 @@ use std::sync::{ atomic::{AtomicBool, Ordering::Relaxed}, Arc, Mutex, }; -use zenoh::plugins::{Plugin, RunningPluginTrait, ValidationFunction, ZenohPlugin}; +use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; @@ -86,46 +86,42 @@ struct RunningPluginInner { #[derive(Clone)] struct RunningPlugin(Arc>); impl RunningPluginTrait for RunningPlugin { - // Operation returning a ValidationFunction(path, old, new)-> ZResult>> - // this function will be called each time the plugin's config is changed via the zenohd admin space - fn config_checker(&self) -> ValidationFunction { - let guard = zlock!(&self.0); - let name = guard.name.clone(); - std::mem::drop(guard); - let plugin = self.clone(); - Arc::new(move |path, old, new| { - const STORAGE_SELECTOR: &str = "storage-selector"; - if path == STORAGE_SELECTOR || path.is_empty() { - match (old.get(STORAGE_SELECTOR), new.get(STORAGE_SELECTOR)) { - (Some(serde_json::Value::String(os)), Some(serde_json::Value::String(ns))) - if os == ns => {} - (_, Some(serde_json::Value::String(selector))) => { - let mut guard = zlock!(&plugin.0); - guard.flag.store(false, Relaxed); - guard.flag = Arc::new(AtomicBool::new(true)); - match KeyExpr::try_from(selector.clone()) { - Err(e) => log::error!("{}", e), - Ok(selector) => { - async_std::task::spawn(run( - guard.runtime.clone(), - selector, - guard.flag.clone(), - )); - } + fn config_checker( + &self, + path: &str, + old: &serde_json::Map, + new: &serde_json::Map, + ) -> ZResult>> { + let mut guard = zlock!(&self.0); + const STORAGE_SELECTOR: &str = "storage-selector"; + if path == STORAGE_SELECTOR || path.is_empty() { + match (old.get(STORAGE_SELECTOR), new.get(STORAGE_SELECTOR)) { + (Some(serde_json::Value::String(os)), Some(serde_json::Value::String(ns))) + if os == ns => {} + (_, Some(serde_json::Value::String(selector))) => { + guard.flag.store(false, Relaxed); + guard.flag = Arc::new(AtomicBool::new(true)); + match KeyExpr::try_from(selector.clone()) { + Err(e) => log::error!("{}", e), + Ok(selector) => { + async_std::task::spawn(run( + guard.runtime.clone(), + selector, + guard.flag.clone(), + )); } - return Ok(None); - } - (_, None) => { - let guard = zlock!(&plugin.0); - guard.flag.store(false, Relaxed); - } - _ => { - bail!("storage-selector for {} must be a string", &name) } + return Ok(None); + } + (_, None) => { + guard.flag.store(false, Relaxed); + } + _ => { + bail!("storage-selector for {} must be a string", &guard.name) } } - bail!("unknown option {} for {}", path, &name) - }) + } + bail!("unknown option {} for {}", path, guard.name) } // Function called on any query on admin space that matches this plugin's sub-part of the admin space. diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 6c908bf92c..f122011495 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -243,10 +243,13 @@ impl Plugin for RestPlugin { struct RunningPlugin(Config); impl RunningPluginTrait for RunningPlugin { - fn config_checker(&self) -> zenoh::plugins::ValidationFunction { - Arc::new(|_, _, _| { - bail!("zenoh-plugin-rest doesn't accept any runtime configuration changes") - }) + fn config_checker( + &self, + _: &str, + _: &serde_json::Map, + _: &serde_json::Map, + ) -> ZResult>> { + bail!("zenoh-plugin-rest doesn't accept any runtime configuration changes") } fn adminspace_getter<'a>( diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 0c4d4778c2..54eb78f95d 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -30,7 +30,7 @@ use std::sync::atomic::AtomicBool; use std::sync::Arc; use std::sync::Mutex; use storages_mgt::StorageMessage; -use zenoh::plugins::{Plugin, RunningPluginTrait, ValidationFunction, ZenohPlugin}; +use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::sync::*; use zenoh::runtime::Runtime; use zenoh::Session; @@ -309,19 +309,21 @@ impl From for StorageRuntime { } impl RunningPluginTrait for StorageRuntime { - fn config_checker(&self) -> ValidationFunction { + fn config_checker( + &self, + _: &str, + old: &serde_json::Map, + new: &serde_json::Map, + ) -> ZResult>> { let name = { zlock!(self.0).name.clone() }; - let runtime = self.0.clone(); - Arc::new(move |_path, old, new| { - let old = PluginConfig::try_from((&name, old))?; - let new = PluginConfig::try_from((&name, new))?; - log::info!("old: {:?}", &old); - log::info!("new: {:?}", &new); - let diffs = ConfigDiff::diffs(old, new); - log::info!("diff: {:?}", &diffs); - { zlock!(runtime).update(diffs) }?; - Ok(None) - }) + let old = PluginConfig::try_from((&name, old))?; + let new = PluginConfig::try_from((&name, new))?; + log::info!("old: {:?}", &old); + log::info!("new: {:?}", &new); + let diffs = ConfigDiff::diffs(old, new); + log::info!("diff: {:?}", &diffs); + { zlock!(self.0).update(diffs) }?; + Ok(None) } fn adminspace_getter<'a>( diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 97a276ad6b..bdde1211c8 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -13,7 +13,7 @@ use super::routing::face::Face; use super::Runtime; use crate::key_expr::KeyExpr; -use crate::plugins::sealed::{self as plugins, ValidationFunction}; +use crate::plugins::sealed::{self as plugins}; use crate::prelude::sync::{Sample, SyncResolve}; use crate::queryable::Query; use crate::queryable::QueryInner; @@ -27,7 +27,7 @@ use std::convert::TryInto; use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::SplitBuffer; -use zenoh_config::ValidatedMap; +use zenoh_config::{ValidatedMap, ValidationFunction}; use zenoh_protocol::{ core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, network::{ @@ -64,8 +64,7 @@ enum PluginDiff { Start(crate::config::PluginLoad), } -fn make_plugin_validator(admin: &Arc) -> ValidationFunction { - let admin = admin.clone(); +fn make_plugin_validator(admin: Arc) -> ValidationFunction { Arc::new(move |name: &_, path: &_, old: &_, new: &_| { let plugins_mgr = zlock!(admin.context.plugins_mgr); if let Some(plugin) = plugins_mgr.plugin(name) { @@ -140,10 +139,13 @@ impl AdminSpace { context, }); - let mut config_guard = admin.context.runtime.state.config.lock(); - for (name, (_, plugin)) in plugins.running_plugins() { - config_guard.add_plugin_validator(name, make_plugin_validator(&admin)) - } + admin + .context + .runtime + .state + .config + .lock() + .set_plugin_validator(make_plugin_validator(admin.clone())); let cfg_rx = admin.context.runtime.state.config.subscribe(); task::spawn({ @@ -211,12 +213,6 @@ impl AdminSpace { match plugins_mgr.start(name, &admin.context.runtime) { Ok(Some((path, _))) => { active_plugins.insert(name.into(), path.into()); - let mut cfg_guard = - admin.context.runtime.state.config.lock(); - cfg_guard.add_plugin_validator( - name, - make_plugin_validator(&admin), - ); log::info!( "Successfully started plugin `{}` from {}", name, diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 037aa50c83..b72dcdc4a9 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -58,10 +58,12 @@ pub trait RunningPluginTrait: Send + Sync { /// Useful when the changes affect settings that aren't hot-configurable for your plugin. /// * `Ok(None)` indicates that the plugin has accepted the configuration change. /// * `Ok(Some(value))` indicates that the plugin would rather the new configuration be `value`. - fn config_checker(&self, - path: &str, - current: &serde_json::Map, - new: &serde_json::Map) -> ZResult>>; + fn config_checker( + &self, + path: &str, + current: &serde_json::Map, + new: &serde_json::Map, + ) -> ZResult>>; /// Used to request your plugin's status for the administration space. fn adminspace_getter<'a>( &'a self, @@ -74,12 +76,3 @@ pub trait RunningPluginTrait: Send + Sync { pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; pub use zenoh_plugin_trait::Plugin; -pub type ValidationFunction = std::sync::Arc< - dyn Fn( - &str, - &serde_json::Map, - &serde_json::Map, - ) -> ZResult>> - + Send - + Sync, ->; From c4e95b900d6f0d6bc7c41a12946589611b82b6ad Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 11 Oct 2023 22:01:29 +0200 Subject: [PATCH 006/106] removed cyclic reference --- commons/zenoh-config/src/lib.rs | 75 +++++++++++++++++------------ zenoh/src/net/runtime/adminspace.rs | 20 +++++--- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 19b2fea6ea..c4e0d53fb0 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -31,7 +31,7 @@ use std::{ marker::PhantomData, net::SocketAddr, path::Path, - sync::{Arc, Mutex, MutexGuard}, + sync::{Arc, Mutex, MutexGuard, Weak}, }; use validated_struct::ValidatedMapAssociatedTypes; pub use validated_struct::{GetError, ValidatedMap}; @@ -46,16 +46,21 @@ use zenoh_protocol::{ use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; -pub type ValidationFunction = std::sync::Arc< - dyn Fn( - &str, // plugin name - &str, // `path`, the relative path from the plugin's configuration root to the changed value. - &serde_json::Map, // `current`, the current configuration of the plugin (from its root). - &serde_json::Map, // `new`, the proposed new configuration of the plugin. - ) -> ZResult>> - + Send - + Sync, ->; +pub trait ConfigValidator: Send + Sync { + fn check_config( + &self, + _plugin_name: &str, + _path: &str, + _current: &serde_json::Map, + _new: &serde_json::Map, + ) -> ZResult>> { + Ok(None) + } +} + +// Necessary to allow to set default emplty weak referece value to plugin.validator field +// because empty weak value is not allowed for Arc +impl ConfigValidator for () {} /// Creates an empty zenoh net Session configuration. pub fn empty() -> Config { @@ -483,7 +488,7 @@ fn config_deser() { } impl Config { - pub fn set_plugin_validator(&mut self, validator: ValidationFunction) { + pub fn set_plugin_validator(&mut self, validator: Weak) { self.plugins.validator = validator; } @@ -837,7 +842,7 @@ fn user_conf_validator(u: &UsrPwdConf) -> bool { #[derive(Clone)] pub struct PluginsConfig { values: Value, - validator: ValidationFunction, + validator: std::sync::Weak, } fn sift_privates(value: &mut serde_json::Value) { match value { @@ -946,14 +951,18 @@ impl PluginsConfig { } other => bail!("{} cannot be indexed", other), } - let new_conf = match (self.validator)( - plugin, - &key[("plugins/".len() + plugin.len())..], - old_conf.as_object().unwrap(), - new_conf.as_object().unwrap(), - )? { - None => new_conf, - Some(new_conf) => Value::Object(new_conf), + let new_conf = if let Some(validator) = self.validator.upgrade() { + match validator.check_config( + plugin, + &key[("plugins/".len() + plugin.len())..], + old_conf.as_object().unwrap(), + new_conf.as_object().unwrap(), + )? { + None => new_conf, + Some(new_conf) => Value::Object(new_conf), + } + } else { + new_conf }; *old_conf = new_conf; Ok(()) @@ -973,7 +982,7 @@ impl Default for PluginsConfig { fn default() -> Self { Self { values: Value::Object(Default::default()), - validator: Arc::new(|_, _, _, _| Ok(None)), + validator: std::sync::Weak::<()>::new(), } } } @@ -983,8 +992,8 @@ impl<'a> serde::Deserialize<'a> for PluginsConfig { D: serde::Deserializer<'a>, { Ok(PluginsConfig { - validator: Arc::new(|_, _, _, _| Ok(None)), values: serde::Deserialize::deserialize(deserializer)?, + validator: std::sync::Weak::<()>::new(), }) } } @@ -1077,15 +1086,17 @@ impl validated_struct::ValidatedMap for PluginsConfig { .entry(plugin) .or_insert(Value::Null); let mut new_value = value.clone().merge(key, new_value)?; - match (self.validator)( - plugin, - key, - value.as_object().unwrap(), - new_value.as_object().unwrap(), - ) { - Ok(Some(val)) => new_value = Value::Object(val), - Ok(None) => {} - Err(e) => return Err(format!("{e}").into()), + if let Some(validator) = self.validator.upgrade() { + match validator.check_config( + plugin, + key, + value.as_object().unwrap(), + new_value.as_object().unwrap(), + ) { + Ok(Some(val)) => new_value = Value::Object(val), + Ok(None) => {} + Err(e) => return Err(format!("{e}").into()), + } } *value = new_value; Ok(()) diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index bdde1211c8..a71382dea2 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -27,7 +27,7 @@ use std::convert::TryInto; use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::SplitBuffer; -use zenoh_config::{ValidatedMap, ValidationFunction}; +use zenoh_config::{ConfigValidator, ValidatedMap}; use zenoh_protocol::{ core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, network::{ @@ -64,15 +64,21 @@ enum PluginDiff { Start(crate::config::PluginLoad), } -fn make_plugin_validator(admin: Arc) -> ValidationFunction { - Arc::new(move |name: &_, path: &_, old: &_, new: &_| { - let plugins_mgr = zlock!(admin.context.plugins_mgr); +impl ConfigValidator for AdminSpace { + fn check_config( + &self, + name: &str, + path: &str, + current: &serde_json::Map, + new: &serde_json::Map, + ) -> ZResult>> { + let plugins_mgr = zlock!(self.context.plugins_mgr); if let Some(plugin) = plugins_mgr.plugin(name) { - plugin.config_checker(path, old, new) + plugin.config_checker(path, current, new) } else { Err(format!("Plugin {name} not found").into()) } - }) + } } impl AdminSpace { @@ -145,7 +151,7 @@ impl AdminSpace { .state .config .lock() - .set_plugin_validator(make_plugin_validator(admin.clone())); + .set_plugin_validator(Arc::downgrade(&admin)); let cfg_rx = admin.context.runtime.state.config.subscribe(); task::spawn({ From 56f43be225a5b20788d2a954827b57b1fdb5a5a9 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 11 Oct 2023 22:07:22 +0200 Subject: [PATCH 007/106] format fix --- zenoh/src/net/runtime/mod.rs | 14 +++++++++++--- zenoh/src/net/runtime/orchestrator.rs | 11 ++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index fbfe24aadc..ea23cd2b51 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -199,7 +199,8 @@ impl Runtime { F: Future + Send + 'static, T: Send + 'static, { - self.state.stop_source + self.state + .stop_source .read() .unwrap() .as_ref() @@ -249,7 +250,11 @@ impl TransportEventHandler for RuntimeTransportEventHandler { Ok(Arc::new(RuntimeSession { runtime: runtime.clone(), endpoint: std::sync::RwLock::new(None), - main_handler: runtime.state.router.new_transport_unicast(transport).unwrap(), + main_handler: runtime + .state + .router + .new_transport_unicast(transport) + .unwrap(), slave_handlers, })) } @@ -268,7 +273,10 @@ impl TransportEventHandler for RuntimeTransportEventHandler { .iter() .filter_map(|handler| handler.new_multicast(transport.clone()).ok()) .collect(); - runtime.state.router.new_transport_multicast(transport.clone())?; + runtime + .state + .router + .new_transport_multicast(transport.clone())?; Ok(Arc::new(RuntimeMuticastGroup { runtime: runtime.clone(), transport, diff --git a/zenoh/src/net/runtime/orchestrator.rs b/zenoh/src/net/runtime/orchestrator.rs index d0b420306d..a1a2c8db48 100644 --- a/zenoh/src/net/runtime/orchestrator.rs +++ b/zenoh/src/net/runtime/orchestrator.rs @@ -829,7 +829,16 @@ impl Runtime { } _ => { if let Some(endpoint) = &*zread!(session.endpoint) { - let peers = { session.runtime.state.config.lock().connect().endpoints().clone() }; + let peers = { + session + .runtime + .state + .config + .lock() + .connect() + .endpoints() + .clone() + }; if peers.contains(endpoint) { let endpoint = endpoint.clone(); let runtime = session.runtime.clone(); From 8d69198b97e79f84ee59a585b18d03fd454558f4 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 11 Oct 2023 22:14:11 +0200 Subject: [PATCH 008/106] clippy fix --- zenoh/src/session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index d83981ed53..ccd255d5bc 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -491,7 +491,7 @@ impl Session { /// # }) /// ``` pub fn config(&self) -> &Notifier { - &self.runtime.config() + self.runtime.config() } /// Get informations about the zenoh [`Session`](Session). From 27ebcd5792a6dc8540f6783bd0332a8c6abc7dfd Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 12 Oct 2023 20:14:59 +0200 Subject: [PATCH 009/106] unfinished --- .../zenoh-plugin-trait/src/compatibility.rs | 49 +++++++++++ plugins/zenoh-plugin-trait/src/lib.rs | 45 +---------- plugins/zenoh-plugin-trait/src/loading.rs | 64 +++++---------- plugins/zenoh-plugin-trait/src/vtable.rs | 81 +++++-------------- 4 files changed, 87 insertions(+), 152 deletions(-) create mode 100644 plugins/zenoh-plugin-trait/src/compatibility.rs diff --git a/plugins/zenoh-plugin-trait/src/compatibility.rs b/plugins/zenoh-plugin-trait/src/compatibility.rs new file mode 100644 index 0000000000..3360baa05b --- /dev/null +++ b/plugins/zenoh-plugin-trait/src/compatibility.rs @@ -0,0 +1,49 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Compatibility { + major: u64, + minor: u64, + patch: u64, + stable: bool, + commit: &'static str, +} +const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); +impl Compatibility { + pub fn new() -> Self { + let (release, commit) = RELEASE_AND_COMMIT; + let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') { + (&release[..p], false) + } else { + (release, true) + }; + let mut split = release.split('.').map(|s| s.trim()); + Compatibility { + major: split.next().unwrap().parse().unwrap(), + minor: split.next().unwrap().parse().unwrap(), + patch: split.next().unwrap().parse().unwrap(), + stable, + commit, + } + } + pub fn are_compatible(a: &Self, b: &Self) -> bool { + if a.stable && b.stable { + a.major == b.major && a.minor == b.minor && a.patch == b.patch + } else { + a == b + } + } +} diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 486aa8fbe7..7605cb2cab 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -18,49 +18,14 @@ //! //! If building a plugin for [`zenohd`](https://crates.io/crates/zenoh), you should use the types exported in [`zenoh::plugins`](https://docs.rs/zenoh/latest/zenoh/plugins) to fill [`Plugin`]'s associated types. //! To check your plugin typing for `zenohd`, have your plugin implement [`zenoh::plugins::ZenohPlugin`](https://docs.rs/zenoh/latest/zenoh/plugins/struct.ZenohPlugin) +pub mod compatibility; pub mod loading; pub mod vtable; use zenoh_result::ZResult; -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Compatibility { - major: u64, - minor: u64, - patch: u64, - stable: bool, - commit: &'static str, -} -const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); -impl Compatibility { - pub fn new() -> ZResult { - let (release, commit) = RELEASE_AND_COMMIT; - let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') { - (&release[..p], false) - } else { - (release, true) - }; - let mut split = release.split('.').map(|s| s.trim()); - Ok(Compatibility { - major: split.next().unwrap().parse().unwrap(), - minor: split.next().unwrap().parse().unwrap(), - patch: split.next().unwrap().parse().unwrap(), - stable, - commit, - }) - } - pub fn are_compatible(a: &Self, b: &Self) -> bool { - if a.stable && b.stable { - a.major == b.major && a.minor == b.minor && a.patch == b.patch - } else { - a == b - } - } -} - pub mod prelude { - pub use crate::{loading::*, vtable::*, Plugin}; + pub use crate::{compatibility::*, loading::*, vtable::*, Plugin}; } pub trait Plugin: Sized + 'static { @@ -68,12 +33,6 @@ pub trait Plugin: Sized + 'static { type RunningPlugin; /// Your plugins' default name when statically linked. const STATIC_NAME: &'static str; - /// You probabky don't need to override this function. - /// - /// Returns some build information on your plugin, allowing the host to detect potential ABI changes that would break it. - fn compatibility() -> ZResult { - Compatibility::new() - } /// Starts your plugin. Use `Ok` to return your plugin's control structure fn start(name: &str, args: &Self::StartArgs) -> ZResult; } diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 0f7475a651..d97ef01561 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -11,12 +11,12 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::vtable::*; use crate::*; use libloading::Library; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::path::PathBuf; +use vtable::PluginVTable; use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; @@ -96,7 +96,6 @@ impl PluginsManager PluginsManager Ok(None), - std::collections::hash_map::Entry::Vacant(e) => { - let compatible = match p.compatibility() { - Some(Ok(c)) => { - if Compatibility::are_compatible(&compat, &c) { - Ok(()) - } else { - Err(zerror!("Plugin compatibility mismatch: host: {:?} - plugin: {:?}. This could lead to segfaults, so wer'e not starting it.", &compat, &c)) - } - } - Some(Err(e)) => Err(zerror!(e => "Plugin {} (from {}) compatibility couldn't be recovered. This likely means it's very broken.", name, path)), - None => Ok(()), - }; - if let Err(e) = compatible { - Err(e.into()) - } else { - match p.start(args) { - Ok(p) => Ok(Some(unsafe { - std::mem::transmute(&e.insert((path.into(), p)).1) - })), - Err(e) => Err(e), - } - } - } + std::collections::hash_map::Entry::Vacant(e) => match p.start(args) { + Ok(p) => Ok(Some(unsafe { + std::mem::transmute(&e.insert((path.into(), p)).1) + })), + Err(e) => Err(e), + }, }, ) }) @@ -218,7 +200,6 @@ trait PluginStarter { fn name(&self) -> &str; fn path(&self) -> &str; fn start(&self, args: &StartArgs) -> ZResult; - fn compatibility(&self) -> Option>; fn deletable(&self) -> bool; } @@ -244,9 +225,6 @@ where fn path(&self) -> &str { "" } - fn compatibility(&self) -> Option> { - None - } fn start(&self, args: &StartArgs) -> ZResult { P::start(P::STATIC_NAME, args) } @@ -265,10 +243,7 @@ impl PluginStarter self.path.to_str().unwrap() } fn start(&self, args: &StartArgs) -> ZResult { - self.vtable.start(self.name(), args) - } - fn compatibility(&self) -> Option> { - Some(self.vtable.compatibility()) + (self.vtable.start)(self.name(), args) } fn deletable(&self) -> bool { true @@ -283,21 +258,18 @@ pub struct DynamicPlugin { } impl DynamicPlugin { - fn new(name: String, lib: Library, path: PathBuf) -> Result> { + fn new(name: String, lib: Library, path: PathBuf) -> Self { + // TODO: check loader version and compatibility let load_plugin = unsafe { - lib.get:: LoadPluginResult>( - b"load_plugin", - ) - .map_err(|_| None)? + lib.get:: PluginVTable>(b"load_plugin") + .map_err(|_| None)? }; - match load_plugin(PLUGIN_VTABLE_VERSION) { - Ok(vtable) => Ok(DynamicPlugin { - _lib: lib, - vtable, - name, - path, - }), - Err(plugin_version) => Err(Some(plugin_version)), + let vtable = load_plugin(); + Self { + _lib: lib, + vtable, + name, + path, } } } diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 6bb3eb7dd5..51193450ed 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -15,73 +15,23 @@ use crate::*; pub use no_mangle::*; use zenoh_result::ZResult; -pub type PluginVTableVersion = u16; -type LoadPluginResultInner = Result, PluginVTableVersion>; -pub type LoadPluginResult = Result, PluginVTableVersion>; - -/// This number should change any time the internal structure of [`PluginVTable`] changes -pub const PLUGIN_VTABLE_VERSION: PluginVTableVersion = 1; +pub type PluginLoaderVersion = u64; +pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; type StartFn = fn(&str, &StartArgs) -> ZResult; -#[repr(C)] -struct PluginVTableInner { - start: StartFn, - compatibility: fn() -> ZResult, -} - -/// Automagical padding such that [PluginVTable::init]'s result is the size of a cache line -#[repr(C)] -struct PluginVTablePadding { - __padding: [u8; PluginVTablePadding::padding_length()], -} -impl PluginVTablePadding { - const fn padding_length() -> usize { - 64 - std::mem::size_of::() - } - fn new() -> Self { - PluginVTablePadding { - __padding: [0; Self::padding_length()], - } - } -} - -/// For use with dynamically loaded plugins. Its size will not change accross versions, but its internal structure might. -/// -/// To ensure compatibility, its size and alignment must allow `size_of::>() == 64` (one cache line). #[repr(C)] pub struct PluginVTable { - inner: PluginVTableInner, - padding: PluginVTablePadding, + pub start: StartFn, } impl PluginVTable { pub fn new>( ) -> Self { - PluginVTable { - inner: PluginVTableInner { - start: ConcretePlugin::start, - compatibility: ConcretePlugin::compatibility, - }, - padding: PluginVTablePadding::new(), + Self { + start: ConcretePlugin::start, } } - - /// Ensures [PluginVTable]'s size stays the same between versions - fn __size_check() { - unsafe { - std::mem::transmute::<_, [u8; 64]>(std::mem::MaybeUninit::< - Result, - >::uninit()) - }; - } - - pub fn start(&self, name: &str, start_args: &StartArgs) -> ZResult { - (self.inner.start)(name, start_args) - } - pub fn compatibility(&self) -> ZResult { - (self.inner.compatibility)() - } } pub use no_mangle::*; @@ -92,17 +42,22 @@ pub mod no_mangle { macro_rules! declare_plugin { ($ty: path) => { #[no_mangle] - fn load_plugin( - version: $crate::prelude::PluginVTableVersion, - ) -> $crate::prelude::LoadPluginResult< + fn get_plugin_loader_version() -> $crate::prelude::PluginLoaderVersion { + $crate::prelude::PLUGIN_LOADER_VERSION + } + + #[no_mangle] + fn get_plugin_compatibility() -> $crate::Compatibility { + // TODO: add vtable version (including type parameters) to the compatibility information + Compatibility::new() + } + + #[no_mangle] + fn load_plugin() -> $crate::prelude::PluginVTable< <$ty as $crate::prelude::Plugin>::StartArgs, <$ty as $crate::prelude::Plugin>::RunningPlugin, > { - if version == $crate::prelude::PLUGIN_VTABLE_VERSION { - Ok($crate::prelude::PluginVTable::new::<$ty>()) - } else { - Err($crate::prelude::PLUGIN_VTABLE_VERSION) - } + $crate::prelude::PluginVTable::new::<$ty>() } }; } From 1dc76621ab01da8dc9ffa8e028148778b4ec0f1c Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 12 Oct 2023 21:59:04 +0200 Subject: [PATCH 010/106] zenoh-plugin-trait corrected --- plugins/zenoh-plugin-trait/src/loading.rs | 19 ++++++------------- plugins/zenoh-plugin-trait/src/vtable.rs | 4 ++-- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index d97ef01561..74a1327d99 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -154,12 +154,7 @@ impl PluginsManager ZResult> { - DynamicPlugin::new(name.into(), lib, path).map_err(|e| - zerror!("Wrong PluginVTable version, your {} doesn't appear to be compatible with this version of Zenoh (vtable versions: plugin v{}, zenoh v{})", - name, - e.map_or_else(|| "UNKNWON".to_string(), |e| e.to_string()), - PLUGIN_VTABLE_VERSION).into() - ) + DynamicPlugin::new(name.into(), lib, path) } pub fn load_plugin_by_name(&mut self, name: String) -> ZResult { @@ -258,18 +253,16 @@ pub struct DynamicPlugin { } impl DynamicPlugin { - fn new(name: String, lib: Library, path: PathBuf) -> Self { + fn new(name: String, lib: Library, path: PathBuf) -> ZResult { // TODO: check loader version and compatibility - let load_plugin = unsafe { - lib.get:: PluginVTable>(b"load_plugin") - .map_err(|_| None)? - }; + let load_plugin = + unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); - Self { + Ok(Self { _lib: lib, vtable, name, path, - } + }) } } diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 51193450ed..4b00bc0f90 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -47,9 +47,9 @@ pub mod no_mangle { } #[no_mangle] - fn get_plugin_compatibility() -> $crate::Compatibility { + fn get_plugin_compatibility() -> $crate::prelude::Compatibility { // TODO: add vtable version (including type parameters) to the compatibility information - Compatibility::new() + $crate::prelude::Compatibility::new() } #[no_mangle] From c059cc04ada4dfc7b7c34ff81a19f4547a35b054 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 13 Oct 2023 00:06:41 +0200 Subject: [PATCH 011/106] version control unfinished --- .../zenoh-plugin-trait/src/compatibility.rs | 49 ----------- plugins/zenoh-plugin-trait/src/lib.rs | 11 ++- plugins/zenoh-plugin-trait/src/vtable.rs | 82 ++++++++++++++++++- 3 files changed, 85 insertions(+), 57 deletions(-) delete mode 100644 plugins/zenoh-plugin-trait/src/compatibility.rs diff --git a/plugins/zenoh-plugin-trait/src/compatibility.rs b/plugins/zenoh-plugin-trait/src/compatibility.rs deleted file mode 100644 index 3360baa05b..0000000000 --- a/plugins/zenoh-plugin-trait/src/compatibility.rs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Compatibility { - major: u64, - minor: u64, - patch: u64, - stable: bool, - commit: &'static str, -} -const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); -impl Compatibility { - pub fn new() -> Self { - let (release, commit) = RELEASE_AND_COMMIT; - let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') { - (&release[..p], false) - } else { - (release, true) - }; - let mut split = release.split('.').map(|s| s.trim()); - Compatibility { - major: split.next().unwrap().parse().unwrap(), - minor: split.next().unwrap().parse().unwrap(), - patch: split.next().unwrap().parse().unwrap(), - stable, - commit, - } - } - pub fn are_compatible(a: &Self, b: &Self) -> bool { - if a.stable && b.stable { - a.major == b.major && a.minor == b.minor && a.patch == b.patch - } else { - a == b - } - } -} diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 7605cb2cab..9440588977 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -18,19 +18,22 @@ //! //! If building a plugin for [`zenohd`](https://crates.io/crates/zenoh), you should use the types exported in [`zenoh::plugins`](https://docs.rs/zenoh/latest/zenoh/plugins) to fill [`Plugin`]'s associated types. //! To check your plugin typing for `zenohd`, have your plugin implement [`zenoh::plugins::ZenohPlugin`](https://docs.rs/zenoh/latest/zenoh/plugins/struct.ZenohPlugin) -pub mod compatibility; pub mod loading; pub mod vtable; use zenoh_result::ZResult; pub mod prelude { - pub use crate::{compatibility::*, loading::*, vtable::*, Plugin}; + pub use crate::{loading::*, vtable::*, Plugin, Version}; +} + +pub trait Version { + fn version() -> u32; } pub trait Plugin: Sized + 'static { - type StartArgs; - type RunningPlugin; + type StartArgs: Version; + type RunningPlugin: Version; /// Your plugins' default name when statically linked. const STATIC_NAME: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 4b00bc0f90..1f2747b549 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -15,8 +15,8 @@ use crate::*; pub use no_mangle::*; use zenoh_result::ZResult; -pub type PluginLoaderVersion = u64; -pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; +pub type CompatibilityVersion = u64; +pub const COMPATIBILITY_VERSION: CompatibilityVersion = 1; type StartFn = fn(&str, &StartArgs) -> ZResult; @@ -25,6 +25,80 @@ pub struct PluginVTable { pub start: StartFn, } +impl Version for PluginVTable { + fn version() -> u32 { + 1 + } +} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Compatibility { + rust_version: RustVersion, + vtable_version: PluginVTableVersion, +} + +impl Compatibility {} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct RustVersion { + major: u64, + minor: u64, + patch: u64, + stable: bool, + commit: &'static str, +} + +const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); +impl RustVersion { + pub fn new() -> Self { + let (release, commit) = RELEASE_AND_COMMIT; + let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') { + (&release[..p], false) + } else { + (release, true) + }; + let mut split = release.split('.').map(|s| s.trim()); + RustVersion { + major: split.next().unwrap().parse().unwrap(), + minor: split.next().unwrap().parse().unwrap(), + patch: split.next().unwrap().parse().unwrap(), + stable, + commit, + } + } + pub fn are_compatible(a: &Self, b: &Self) -> bool { + if a.stable && b.stable { + a.major == b.major && a.minor == b.minor && a.patch == b.patch + } else { + a == b + } + } +} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct PluginVTableVersion { + vtable_version: u32, + start_args_type_version: u32, + running_plugin_type_version: u32, + start_args_type_name: &'static str, + running_plugin_type_name: &'static str, +} + +impl PluginVTableVersion { + pub fn new() -> Self { + Self { + vtable_version: 1, + start_args_type_version: 1, + running_plugin_type_version: 1, + start_args_type_name: std::any::type_name::(), + running_plugin_type_name: std::any::type_name::(), + } + } +} + impl PluginVTable { pub fn new>( ) -> Self { @@ -42,12 +116,12 @@ pub mod no_mangle { macro_rules! declare_plugin { ($ty: path) => { #[no_mangle] - fn get_plugin_loader_version() -> $crate::prelude::PluginLoaderVersion { + fn get_compatibility_version() -> $crate::prelude::CompatibilityVersion { $crate::prelude::PLUGIN_LOADER_VERSION } #[no_mangle] - fn get_plugin_compatibility() -> $crate::prelude::Compatibility { + fn get_compatibility() -> $crate::prelude::Compatibility { // TODO: add vtable version (including type parameters) to the compatibility information $crate::prelude::Compatibility::new() } From ee44f0eca5ba8012e312375d46876ea00275f481 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 13 Oct 2023 12:04:11 +0000 Subject: [PATCH 012/106] loader compatibility version --- plugins/zenoh-plugin-trait/src/lib.rs | 8 ++-- plugins/zenoh-plugin-trait/src/vtable.rs | 60 +++++++++++++----------- zenoh/src/net/runtime/mod.rs | 7 +++ zenoh/src/plugins/sealed.rs | 7 +++ 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 9440588977..517db1fbc8 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -24,16 +24,16 @@ pub mod vtable; use zenoh_result::ZResult; pub mod prelude { - pub use crate::{loading::*, vtable::*, Plugin, Version}; + pub use crate::{loading::*, vtable::*, Plugin, CompatibilityVersion}; } -pub trait Version { +pub trait CompatibilityVersion { fn version() -> u32; } pub trait Plugin: Sized + 'static { - type StartArgs: Version; - type RunningPlugin: Version; + type StartArgs: CompatibilityVersion; + type RunningPlugin: CompatibilityVersion; /// Your plugins' default name when statically linked. const STATIC_NAME: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 1f2747b549..9b6e67841c 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -15,8 +15,8 @@ use crate::*; pub use no_mangle::*; use zenoh_result::ZResult; -pub type CompatibilityVersion = u64; -pub const COMPATIBILITY_VERSION: CompatibilityVersion = 1; +pub type PluginLoaderVersion = u64; +pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; type StartFn = fn(&str, &StartArgs) -> ZResult; @@ -24,8 +24,7 @@ type StartFn = fn(&str, &StartArgs) -> ZResult { pub start: StartFn, } - -impl Version for PluginVTable { +impl CompatibilityVersion for PluginVTable { fn version() -> u32 { 1 } @@ -35,10 +34,30 @@ impl Version for PluginVTable() -> Self { + Self { + rust_version: RustVersion::new(), + vtable_version: PluginVTable::::version(), + start_args_version: (std::any::type_name::(), StartArgs::version()), + running_plugin_version: ( + std::any::type_name::(), + RunningPlugin::version(), + ), + } + } + pub fn are_compatible(&self, other: &Self) -> bool { + RustVersion::are_compatible(&self.rust_version, &other.rust_version) + && self.vtable_version == other.vtable_version + && self.start_args_version == other.start_args_version + && self.running_plugin_version == other.running_plugin_version + } +} #[repr(C)] #[derive(Debug, PartialEq, Eq, Clone)] @@ -77,25 +96,9 @@ impl RustVersion { } } -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct PluginVTableVersion { - vtable_version: u32, - start_args_type_version: u32, - running_plugin_type_version: u32, - start_args_type_name: &'static str, - running_plugin_type_name: &'static str, -} - -impl PluginVTableVersion { - pub fn new() -> Self { - Self { - vtable_version: 1, - start_args_type_version: 1, - running_plugin_type_version: 1, - start_args_type_name: std::any::type_name::(), - running_plugin_type_name: std::any::type_name::(), - } +impl Default for RustVersion { + fn default() -> Self { + Self::new() } } @@ -116,14 +119,17 @@ pub mod no_mangle { macro_rules! declare_plugin { ($ty: path) => { #[no_mangle] - fn get_compatibility_version() -> $crate::prelude::CompatibilityVersion { + fn get_plugin_loader_version() -> $crate::prelude::PluginLoaderVersion { $crate::prelude::PLUGIN_LOADER_VERSION } #[no_mangle] fn get_compatibility() -> $crate::prelude::Compatibility { // TODO: add vtable version (including type parameters) to the compatibility information - $crate::prelude::Compatibility::new() + $crate::prelude::Compatibility::new::< + <$ty as $crate::prelude::Plugin>::StartArgs, + <$ty as $crate::prelude::Plugin>::RunningPlugin, + >() } #[no_mangle] diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index ea23cd2b51..ab6c75dc9a 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -30,6 +30,7 @@ pub use adminspace::AdminSpace; use async_std::task::JoinHandle; use futures::stream::StreamExt; use futures::Future; +use zenoh_plugin_trait::CompatibilityVersion; use std::any::Any; use std::sync::Arc; use std::time::Duration; @@ -64,6 +65,12 @@ pub struct Runtime { state: Arc, } +impl CompatibilityVersion for Runtime { + fn version() -> u32 { + 1 + } +} + impl Runtime { pub async fn new(config: Config) -> ZResult { let mut runtime = Runtime::init(config).await?; diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index b72dcdc4a9..a66042db7a 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -31,6 +31,12 @@ pub type StartArgs = Runtime; /// A zenoh plugin, when started, must return this type. pub type RunningPlugin = Box; +impl CompatibilityVersion for RunningPlugin { + fn version() -> u32 { + 1 + } +} + #[non_exhaustive] #[derive(serde::Serialize, Debug, Clone)] /// A Response for the administration space. @@ -75,4 +81,5 @@ pub trait RunningPluginTrait: Send + Sync { /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; +use zenoh_plugin_trait::CompatibilityVersion; pub use zenoh_plugin_trait::Plugin; From b1780e1a9b3de4e55b917893b1843cef38cff334 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 13 Oct 2023 14:38:22 +0000 Subject: [PATCH 013/106] string version with features --- Cargo.lock | 1 + plugins/zenoh-plugin-trait/src/lib.rs | 10 ++++++++- plugins/zenoh-plugin-trait/src/loading.rs | 26 +++++++++++++++++------ plugins/zenoh-plugin-trait/src/vtable.rs | 10 ++++----- zenoh/Cargo.toml | 1 + zenoh/src/net/runtime/mod.rs | 25 +++++++++++++++++++--- zenoh/src/plugins/sealed.rs | 6 +++--- zenohd/src/main.rs | 1 + 8 files changed, 62 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e4c4bcc18..8ebec57332 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4473,6 +4473,7 @@ dependencies = [ "async-std", "async-trait", "base64 0.21.4", + "const_format", "env_logger", "event-listener", "flume", diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 517db1fbc8..c21655e5c4 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -27,8 +27,16 @@ pub mod prelude { pub use crate::{loading::*, vtable::*, Plugin, CompatibilityVersion}; } +#[macro_export] +macro_rules! version_with_features { + ($version:literal, $($feature:literal),*) => { + concatcp!($version $(, + if cfg!(feature = $feature) { concatcp!(" ", $feature) } else { "" } + )*) + }; +} pub trait CompatibilityVersion { - fn version() -> u32; + fn version() -> &'static str; } pub trait Plugin: Sized + 'static { diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 74a1327d99..1ca1320470 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -16,19 +16,19 @@ use libloading::Library; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::path::PathBuf; -use vtable::PluginVTable; +use vtable::{PluginVTable, PluginLoaderVersion, PLUGIN_LOADER_VERSION, Compatibility}; use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. -pub struct PluginsManager { +pub struct PluginsManager { loader: Option, plugin_starters: Vec + Send + Sync>>, running_plugins: HashMap, } -impl PluginsManager { +impl PluginsManager { /// Constructs a new plugin manager with dynamic library loading enabled. pub fn dynamic(loader: LibLoader) -> Self { PluginsManager { @@ -228,7 +228,7 @@ where } } -impl PluginStarter +impl PluginStarter for DynamicPlugin { fn name(&self) -> &str { @@ -245,15 +245,29 @@ impl PluginStarter } } -pub struct DynamicPlugin { +pub struct DynamicPlugin { _lib: Library, vtable: PluginVTable, pub name: String, pub path: PathBuf, } -impl DynamicPlugin { +impl DynamicPlugin { fn new(name: String, lib: Library, path: PathBuf) -> ZResult { + let get_plugin_loader_version = unsafe { + lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? + }; + let plugin_loader_version = get_plugin_loader_version(); + if plugin_loader_version != PLUGIN_LOADER_VERSION { + bail!("Plugin loader version mismatch: host = {}, plugin = {}", PLUGIN_LOADER_VERSION, plugin_loader_version); + } + let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; + let plugin_compatibility_record = get_compatibility(); + let host_compatibility_record = Compatibility::new::(); + if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { + bail!("Plugin compatibility mismatch:\nhost = {:?}\nplugin = {:?}\n", host_compatibility_record, plugin_compatibility_record); + } + // TODO: check loader version and compatibility let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 9b6e67841c..59caf399b7 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -25,8 +25,8 @@ pub struct PluginVTable { pub start: StartFn, } impl CompatibilityVersion for PluginVTable { - fn version() -> u32 { - 1 + fn version() -> &'static str{ + "1" } } @@ -34,9 +34,9 @@ impl CompatibilityVersion for PluginVTable u32 { - 1 + fn version() -> &'static str { + version_with_features!( + "1", + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ) } } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index a66042db7a..da75ea6711 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -32,8 +32,8 @@ pub type StartArgs = Runtime; pub type RunningPlugin = Box; impl CompatibilityVersion for RunningPlugin { - fn version() -> u32 { - 1 + fn version() -> &'static str { + "1" } } @@ -81,5 +81,5 @@ pub trait RunningPluginTrait: Send + Sync { /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; -use zenoh_plugin_trait::CompatibilityVersion; +pub use zenoh_plugin_trait::CompatibilityVersion; pub use zenoh_plugin_trait::Plugin; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 28df513a46..820e29d9c1 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -20,6 +20,7 @@ use zenoh::config::{Config, ModeDependentValue, PermissionsConf, PluginLoad, Val use zenoh::plugins::PluginsManager; use zenoh::prelude::{EndPoint, WhatAmI}; use zenoh::runtime::{AdminSpace, Runtime}; +use zenoh::plugins::CompatibilityVersion; const GIT_VERSION: &str = git_version!(prefix = "v", cargo_prefix = "v"); From 63346f0bd59c218e13ee4d9444e1c0403fc68e56 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 16 Oct 2023 12:46:43 +0200 Subject: [PATCH 014/106] concat_enabled_features --- plugins/zenoh-plugin-trait/src/lib.rs | 15 +++++++++------ zenoh/src/net/runtime/mod.rs | 8 +++++--- zenoh/src/plugins/sealed.rs | 23 ++++++++++++++++++++++- zenohd/src/main.rs | 1 - 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index c21655e5c4..d6b4475bcb 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -24,15 +24,18 @@ pub mod vtable; use zenoh_result::ZResult; pub mod prelude { - pub use crate::{loading::*, vtable::*, Plugin, CompatibilityVersion}; + pub use crate::{loading::*, vtable::*, CompatibilityVersion, Plugin}; } #[macro_export] -macro_rules! version_with_features { - ($version:literal, $($feature:literal),*) => { - concatcp!($version $(, - if cfg!(feature = $feature) { concatcp!(" ", $feature) } else { "" } - )*) +macro_rules! concat_enabled_features { + ($version:ident, $($feature:literal),*) => { + { + use const_format::concatcp; + const_format::concatcp!($version $(, + if cfg!(feature = $feature) { concatcp!(" ", $feature) } else { "" } + )*) + } }; } pub trait CompatibilityVersion { diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 509aac0dac..f3ca4a78db 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -38,7 +38,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::{CompatibilityVersion, version_with_features}; +use zenoh_plugin_trait::{CompatibilityVersion, concat_enabled_features}; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; @@ -66,10 +66,12 @@ pub struct Runtime { state: Arc, } +const RUNTIME_VERSION: &str = "1"; + impl CompatibilityVersion for Runtime { fn version() -> &'static str { - version_with_features!( - "1", + concat_enabled_features!( + RUNTIME_VERSION, "auth_pubkey", "auth_usrpwd", "complete_n", diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index da75ea6711..5b2d48374b 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -31,9 +31,29 @@ pub type StartArgs = Runtime; /// A zenoh plugin, when started, must return this type. pub type RunningPlugin = Box; +const RUNNING_PLUGIN_VERSION: &str = "1"; + impl CompatibilityVersion for RunningPlugin { fn version() -> &'static str { - "1" + concat_enabled_features!( + RUNNING_PLUGIN_VERSION, + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ) } } @@ -81,5 +101,6 @@ pub trait RunningPluginTrait: Send + Sync { /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; +use zenoh_plugin_trait::concat_enabled_features; pub use zenoh_plugin_trait::CompatibilityVersion; pub use zenoh_plugin_trait::Plugin; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 820e29d9c1..28df513a46 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -20,7 +20,6 @@ use zenoh::config::{Config, ModeDependentValue, PermissionsConf, PluginLoad, Val use zenoh::plugins::PluginsManager; use zenoh::prelude::{EndPoint, WhatAmI}; use zenoh::runtime::{AdminSpace, Runtime}; -use zenoh::plugins::CompatibilityVersion; const GIT_VERSION: &str = git_version!(prefix = "v", cargo_prefix = "v"); From a91e0cfe1dff61cfa71ef30025b5dd2b79353da7 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 17 Oct 2023 20:37:46 +0200 Subject: [PATCH 015/106] example storage plugin --- Cargo.lock | 19 ++++ Cargo.toml | 1 + DEFAULT_CONFIG.json5 | 18 ++-- plugins/example-storage-plugin/Cargo.toml | 39 ++++++++ plugins/example-storage-plugin/src/lib.rs | 90 +++++++++++++++++++ .../zenoh-plugin-storage-manager/config.json5 | 17 ++-- 6 files changed, 168 insertions(+), 16 deletions(-) create mode 100644 plugins/example-storage-plugin/Cargo.toml create mode 100644 plugins/example-storage-plugin/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8ebec57332..715da2c689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4880,6 +4880,25 @@ dependencies = [ "zenoh-util", ] +[[package]] +name = "zenoh-plugin-storage-example" +version = "0.11.0-dev" +dependencies = [ + "async-std", + "async-trait", + "clap 3.2.25", + "env_logger", + "futures", + "log", + "serde_json", + "zenoh", + "zenoh-core", + "zenoh-plugin-trait", + "zenoh-result", + "zenoh-util", + "zenoh_backend_traits", +] + [[package]] name = "zenoh-plugin-storage-manager" version = "0.11.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 157ba72da2..8cea280db9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ members = [ "io/zenoh-links/zenoh-link-unixpipe/", "io/zenoh-transport", "plugins/example-plugin", + "plugins/example-storage-plugin", "plugins/zenoh-backend-traits", "plugins/zenoh-plugin-rest", "plugins/zenoh-plugin-storage-manager", diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index dae3ebc9aa..1ff25a0c22 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -393,14 +393,14 @@ // }, // }, - // /// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // } - // }, + /// Plugin configuration example using `__config__` property + plugins: { + rest: { + __config__: "./plugins/zenoh-plugin-rest/config.json5", + }, + storage_manager: { + __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + } + }, } diff --git a/plugins/example-storage-plugin/Cargo.toml b/plugins/example-storage-plugin/Cargo.toml new file mode 100644 index 0000000000..37465b5f87 --- /dev/null +++ b/plugins/example-storage-plugin/Cargo.toml @@ -0,0 +1,39 @@ +# +# Copyright (c) 2023 ZettaScale Technology +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +# which is available at https://www.apache.org/licenses/LICENSE-2.0. +# +# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +# +# Contributors: +# ZettaScale Zenoh Team, +# +[package] +rust-version = { workspace = true } +name = "zenoh-plugin-storage-example" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } + +[lib] +name = "zenoh_backend_example" +# This crate type will make `cargo` output a dynamic library instead of a rust static library +crate-type = ["cdylib"] + +[dependencies] +async-std = { workspace = true, features = ["default"] } +clap = { workspace = true } +env_logger = { workspace = true } +futures = { workspace = true } +log = { workspace = true } +serde_json = { workspace = true } +zenoh = { workspace = true } +zenoh-core = { workspace = true } +zenoh-plugin-trait = { workspace = true } +zenoh-result = { workspace = true } +zenoh-util = { workspace = true } +async-trait = { workspace = true } +zenoh_backend_traits = { workspace = true } diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs new file mode 100644 index 0000000000..ff21798992 --- /dev/null +++ b/plugins/example-storage-plugin/src/lib.rs @@ -0,0 +1,90 @@ +use std::sync::Arc; + +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use async_trait::async_trait; +use zenoh::{prelude::OwnedKeyExpr, sample::Sample, time::Timestamp, value::Value}; +use zenoh_backend_traits::{ + config::{StorageConfig, VolumeConfig}, + Capability, History, Persistence, Storage, StorageInsertionResult, StoredData, Volume, +}; +use zenoh_result::ZResult; + +#[no_mangle] +pub fn create_volume(_config: VolumeConfig) -> ZResult> { + let volume = ExampleBackendStorage {}; + Ok(Box::new(volume)) +} + +pub struct ExampleBackendStorage {} + +pub struct ExampleStorage {} + +#[async_trait] +impl Volume for ExampleBackendStorage { + fn get_admin_status(&self) -> serde_json::Value { + serde_json::Value::Null + } + fn get_capability(&self) -> Capability { + Capability { + persistence: Persistence::Volatile, + history: History::Latest, + read_cost: 0, + } + } + async fn create_storage(&mut self, _props: StorageConfig) -> ZResult> { + Ok(Box::new(ExampleStorage {})) + } + fn incoming_data_interceptor(&self) -> Option Sample + Send + Sync>> { + None + } + fn outgoing_data_interceptor(&self) -> Option Sample + Send + Sync>> { + None + } +} + +#[async_trait] +impl Storage for ExampleStorage { + fn get_admin_status(&self) -> serde_json::Value { + serde_json::Value::Null + } + async fn put( + &mut self, + _key: Option, + _value: Value, + _timestamp: Timestamp, + ) -> ZResult { + Ok(StorageInsertionResult::Inserted) + } + + async fn delete( + &mut self, + _key: Option, + _timestamp: Timestamp, + ) -> ZResult { + Ok(StorageInsertionResult::Deleted) + } + + async fn get( + &mut self, + _key: Option, + _parameters: &str, + ) -> ZResult> { + Ok(Vec::new()) + } + + async fn get_all_entries(&self) -> ZResult, Timestamp)>> { + Ok(Vec::new()) + } +} diff --git a/plugins/zenoh-plugin-storage-manager/config.json5 b/plugins/zenoh-plugin-storage-manager/config.json5 index 5f2f1c3195..204fa27e96 100644 --- a/plugins/zenoh-plugin-storage-manager/config.json5 +++ b/plugins/zenoh-plugin-storage-manager/config.json5 @@ -1,13 +1,16 @@ { "volumes": { - "influxdb_local": { - "__path__": "../zenoh-backend-influxdb/target/debug/libzenoh_backend_influxdb.dylib", - "__config__": "config_influxdb_local.json5" - }, - "influxdb_remote": { - "__path__": "../zenoh-backend-influxdb/target/debug/libzenoh_backend_influxdb.dylib", - "__config__": "config_influxdb_remote.json5" + "example" : { + "__path__": "./plugins/example-storage-plugin/target/debug/libexample_storage_plugin.dylib", } + //"influxdb_local": { + // "__path__": "../zenoh-backend-influxdb/target/debug/libzenoh_backend_influxdb.dylib", + // "__config__": "config_influxdb_local.json5" + //}, + //"influxdb_remote": { + // "__path__": "../zenoh-backend-influxdb/target/debug/libzenoh_backend_influxdb.dylib", + // "__config__": "config_influxdb_remote.json5" + //} }, "storages": {} } \ No newline at end of file From 5fdbe66dd303f1072b0c04d7f40b9af61ab69d85 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 18 Oct 2023 15:39:22 +0200 Subject: [PATCH 016/106] config corrected for example storage plugin --- plugins/example-storage-plugin/config.json5 | 1 + plugins/zenoh-plugin-storage-manager/config.json5 | 13 +++---------- .../config_influxdb_local.json5 | 7 ------- .../config_influxdb_remote.json5 | 7 ------- plugins/zenoh-plugin-storage-manager/src/lib.rs | 5 ++--- 5 files changed, 6 insertions(+), 27 deletions(-) create mode 100644 plugins/example-storage-plugin/config.json5 delete mode 100644 plugins/zenoh-plugin-storage-manager/config_influxdb_local.json5 delete mode 100644 plugins/zenoh-plugin-storage-manager/config_influxdb_remote.json5 diff --git a/plugins/example-storage-plugin/config.json5 b/plugins/example-storage-plugin/config.json5 new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/plugins/example-storage-plugin/config.json5 @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/plugins/zenoh-plugin-storage-manager/config.json5 b/plugins/zenoh-plugin-storage-manager/config.json5 index 204fa27e96..712cc2a513 100644 --- a/plugins/zenoh-plugin-storage-manager/config.json5 +++ b/plugins/zenoh-plugin-storage-manager/config.json5 @@ -1,16 +1,9 @@ { "volumes": { - "example" : { - "__path__": "./plugins/example-storage-plugin/target/debug/libexample_storage_plugin.dylib", + "example": { + "__path__": "target/debug/libzenoh_backend_example.so", + "__config__": "../../plugins/example-storage-plugin/config.json5" } - //"influxdb_local": { - // "__path__": "../zenoh-backend-influxdb/target/debug/libzenoh_backend_influxdb.dylib", - // "__config__": "config_influxdb_local.json5" - //}, - //"influxdb_remote": { - // "__path__": "../zenoh-backend-influxdb/target/debug/libzenoh_backend_influxdb.dylib", - // "__config__": "config_influxdb_remote.json5" - //} }, "storages": {} } \ No newline at end of file diff --git a/plugins/zenoh-plugin-storage-manager/config_influxdb_local.json5 b/plugins/zenoh-plugin-storage-manager/config_influxdb_local.json5 deleted file mode 100644 index b627f9eb89..0000000000 --- a/plugins/zenoh-plugin-storage-manager/config_influxdb_local.json5 +++ /dev/null @@ -1,7 +0,0 @@ -{ - url: "https://localhost:8086", - private: { - username: "user1", - password: "pw1", - }, -} \ No newline at end of file diff --git a/plugins/zenoh-plugin-storage-manager/config_influxdb_remote.json5 b/plugins/zenoh-plugin-storage-manager/config_influxdb_remote.json5 deleted file mode 100644 index b034b4c77a..0000000000 --- a/plugins/zenoh-plugin-storage-manager/config_influxdb_remote.json5 +++ /dev/null @@ -1,7 +0,0 @@ -{ - url: "https://myinfluxdb.example", - private: { - username: "user1", - password: "pw1", - }, -} \ No newline at end of file diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 54eb78f95d..613eae97d0 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -170,13 +170,12 @@ impl StorageRuntimeInner { for path in paths { unsafe { if let Ok((lib, path)) = LibLoader::load_file(path) { - self.loaded_backend_from_lib( + return self.loaded_backend_from_lib( &volume_id, config.clone(), lib, path, - )?; - break; + ); } } } From be46e365236e5b1f04f2e64041f1c3ac16311828 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 19 Oct 2023 17:16:12 +0200 Subject: [PATCH 017/106] example storage plugin works as memory one --- plugins/example-storage-plugin/src/lib.rs | 58 ++++++++++++++----- .../zenoh-plugin-storage-manager/config.json5 | 13 ++++- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index ff21798992..a3a50504e0 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -1,5 +1,6 @@ -use std::sync::Arc; +use std::{collections::{hash_map::Entry, HashMap}, sync::Arc}; +use async_std::sync::RwLock; // // Copyright (c) 2023 ZettaScale Technology // @@ -23,16 +24,26 @@ use zenoh_result::ZResult; #[no_mangle] pub fn create_volume(_config: VolumeConfig) -> ZResult> { - let volume = ExampleBackendStorage {}; + let volume = ExampleBackend {}; Ok(Box::new(volume)) } -pub struct ExampleBackendStorage {} +pub struct ExampleBackend {} -pub struct ExampleStorage {} +pub struct ExampleStorage { + map: RwLock, StoredData>>, +} + +impl Default for ExampleStorage { + fn default() -> Self { + Self { + map: RwLock::new(HashMap::new()), + } + } +} #[async_trait] -impl Volume for ExampleBackendStorage { +impl Volume for ExampleBackend { fn get_admin_status(&self) -> serde_json::Value { serde_json::Value::Null } @@ -44,7 +55,7 @@ impl Volume for ExampleBackendStorage { } } async fn create_storage(&mut self, _props: StorageConfig) -> ZResult> { - Ok(Box::new(ExampleStorage {})) + Ok(Box::new(ExampleStorage::default())) } fn incoming_data_interceptor(&self) -> Option Sample + Send + Sync>> { None @@ -61,30 +72,49 @@ impl Storage for ExampleStorage { } async fn put( &mut self, - _key: Option, - _value: Value, - _timestamp: Timestamp, + key: Option, + value: Value, + timestamp: Timestamp, ) -> ZResult { - Ok(StorageInsertionResult::Inserted) + let mut map = self.map.write().await; + match map.entry(key) { + Entry::Occupied(mut e) => { + e.insert(StoredData { value, timestamp }); + return Ok(StorageInsertionResult::Replaced); + } + Entry::Vacant(e) => { + e.insert(StoredData { value, timestamp }); + return Ok(StorageInsertionResult::Inserted); + } + } } async fn delete( &mut self, - _key: Option, + key: Option, _timestamp: Timestamp, ) -> ZResult { + self.map.write().await.remove_entry(&key); Ok(StorageInsertionResult::Deleted) } async fn get( &mut self, - _key: Option, + key: Option, _parameters: &str, ) -> ZResult> { - Ok(Vec::new()) + match self.map.read().await.get(&key) { + Some(v) => Ok(vec![v.clone()]), + None => Err(format!("Key {:?} is not present", key).into()), + } } async fn get_all_entries(&self) -> ZResult, Timestamp)>> { - Ok(Vec::new()) + let map = self.map.read().await; + let mut result = Vec::with_capacity(map.len()); + for (k, v) in map.iter() { + result.push((k.clone(), v.timestamp)); + } + Ok(result) } } diff --git a/plugins/zenoh-plugin-storage-manager/config.json5 b/plugins/zenoh-plugin-storage-manager/config.json5 index 712cc2a513..3b3cd51ff5 100644 --- a/plugins/zenoh-plugin-storage-manager/config.json5 +++ b/plugins/zenoh-plugin-storage-manager/config.json5 @@ -1,9 +1,18 @@ { "volumes": { "example": { - "__path__": "target/debug/libzenoh_backend_example.so", + "__path__": ["target/debug/libzenoh_backend_example.so","target/debug/libzenoh_backend_example.dylib"], "__config__": "../../plugins/example-storage-plugin/config.json5" } }, - "storages": {} + "storages": { + "memory": { + "volume": "memory", + "key_expr": "demo/memory/**" + }, + "example": { + "volume": "example", + "key_expr": "demo/example/**" + } + } } \ No newline at end of file From 89e67ddde295471f8e59dd39a718ca3c01894734 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 19 Oct 2023 18:02:56 +0200 Subject: [PATCH 018/106] support load api from example stroage plugin --- Cargo.lock | 2 ++ plugins/example-storage-plugin/src/lib.rs | 23 ++++++++++++++-- plugins/zenoh-backend-traits/Cargo.toml | 4 ++- plugins/zenoh-backend-traits/src/config.rs | 31 +++++++++++++++++++++- plugins/zenoh-backend-traits/src/lib.rs | 29 ++++++++++++++++++++ plugins/zenoh-plugin-trait/src/lib.rs | 2 +- 6 files changed, 86 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 715da2c689..8ff6e7cfd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5057,10 +5057,12 @@ version = "0.11.0-dev" dependencies = [ "async-std", "async-trait", + "const_format", "derive_more", "schemars", "serde_json", "zenoh", + "zenoh-plugin-trait", "zenoh-result", "zenoh-util", ] diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index a3a50504e0..a6d5d9760a 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -1,4 +1,7 @@ -use std::{collections::{hash_map::Entry, HashMap}, sync::Arc}; +use std::{ + collections::{hash_map::Entry, HashMap}, + sync::Arc, +}; use async_std::sync::RwLock; // @@ -19,9 +22,25 @@ use zenoh::{prelude::OwnedKeyExpr, sample::Sample, time::Timestamp, value::Value use zenoh_backend_traits::{ config::{StorageConfig, VolumeConfig}, Capability, History, Persistence, Storage, StorageInsertionResult, StoredData, Volume, + VolumePlugin, }; +use zenoh_plugin_trait::Plugin; use zenoh_result::ZResult; +zenoh_plugin_trait::declare_plugin!(ExampleBackend); + +impl Plugin for ExampleBackend { + type StartArgs = VolumeConfig; + type RunningPlugin = VolumePlugin; + + fn start(_name: &str, _args: &Self::StartArgs) -> ZResult { + let volume = ExampleBackend {}; + Ok(Box::new(volume)) + } + + const STATIC_NAME: &'static str = "example_backend"; +} + #[no_mangle] pub fn create_volume(_config: VolumeConfig) -> ZResult> { let volume = ExampleBackend {}; @@ -55,7 +74,7 @@ impl Volume for ExampleBackend { } } async fn create_storage(&mut self, _props: StorageConfig) -> ZResult> { - Ok(Box::new(ExampleStorage::default())) + Ok(Box::::default()) } fn incoming_data_interceptor(&self) -> Option Sample + Send + Sync>> { None diff --git a/plugins/zenoh-backend-traits/Cargo.toml b/plugins/zenoh-backend-traits/Cargo.toml index b9a6cef183..8c13247c5e 100644 --- a/plugins/zenoh-backend-traits/Cargo.toml +++ b/plugins/zenoh-backend-traits/Cargo.toml @@ -34,4 +34,6 @@ serde_json = { workspace = true } zenoh = { workspace = true } zenoh-result = { workspace = true } zenoh-util = { workspace = true } -schemars = { workspace = true } \ No newline at end of file +schemars = { workspace = true } +zenoh-plugin-trait = { workspace = true } +const_format = { workspace = true } \ No newline at end of file diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index ba9ac3b2bc..20c3d5f3f4 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -16,7 +16,10 @@ use schemars::JsonSchema; use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; -use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; +use zenoh::{ + key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult, +}; +use zenoh_plugin_trait::{CompatibilityVersion, concat_enabled_features}; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] @@ -67,6 +70,32 @@ pub struct ReplicaConfig { pub delta: Duration, } +const VOLUME_CONFIG_VERSION: &str = "1"; + +impl CompatibilityVersion for VolumeConfig { + fn version() -> &'static str { + concat_enabled_features!( + VOLUME_CONFIG_VERSION, + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ) + } +} + impl Default for ReplicaConfig { fn default() -> Self { Self { diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index ac1e1c973c..8ab5844de9 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -132,6 +132,7 @@ //! ``` use async_trait::async_trait; +use zenoh_plugin_trait::{CompatibilityVersion, concat_enabled_features}; use std::sync::Arc; use zenoh::prelude::{KeyExpr, OwnedKeyExpr, Sample, Selector}; use zenoh::queryable::ReplyBuilder; @@ -214,6 +215,34 @@ pub trait Volume: Send + Sync { fn outgoing_data_interceptor(&self) -> Option Sample + Send + Sync>>; } +pub type VolumePlugin = Box; + +const VOLUME_PLUGIN_VERSION: &str = "1"; + +impl CompatibilityVersion for VolumePlugin { + fn version() -> &'static str { + concat_enabled_features!( + VOLUME_PLUGIN_VERSION, + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ) + } +} + /// Trait to be implemented by a Storage. #[async_trait] pub trait Storage: Send + Sync { diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index d6b4475bcb..47b9d153bb 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -24,7 +24,7 @@ pub mod vtable; use zenoh_result::ZResult; pub mod prelude { - pub use crate::{loading::*, vtable::*, CompatibilityVersion, Plugin}; + pub use crate::{loading::*, vtable::*, CompatibilityVersion, Plugin, concat_enabled_features}; } #[macro_export] From 84442f5a2e101485c7013e16cab9fb6629fad388 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 22 Oct 2023 20:33:52 +0200 Subject: [PATCH 019/106] unifying plugn loading unfinished --- plugins/zenoh-backend-traits/src/config.rs | 23 +++---- .../zenoh-plugin-storage-manager/src/lib.rs | 56 ++++++----------- .../src/memory_backend/mod.rs | 2 +- plugins/zenoh-plugin-trait/src/loading.rs | 62 +++++++++++++------ zenoh/src/net/runtime/adminspace.rs | 13 ++-- zenohd/src/main.rs | 2 +- 6 files changed, 80 insertions(+), 78 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index 20c3d5f3f4..2672a2f346 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -16,10 +16,8 @@ use schemars::JsonSchema; use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; -use zenoh::{ - key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult, -}; -use zenoh_plugin_trait::{CompatibilityVersion, concat_enabled_features}; +use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; +use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] @@ -251,10 +249,6 @@ impl ConfigDiff { diffs } } -pub enum BackendSearchMethod<'a> { - ByPaths(&'a [String]), - ByName(&'a str), -} impl VolumeConfig { pub fn to_json_value(&self) -> Value { let mut result = self.rest.clone(); @@ -269,11 +263,14 @@ impl VolumeConfig { } Value::Object(result) } - pub fn backend_search_method(&self) -> BackendSearchMethod { - match &self.paths { - None => BackendSearchMethod::ByName(self.backend.as_deref().unwrap_or(&self.name)), - Some(paths) => BackendSearchMethod::ByPaths(paths), - } + pub fn name(&self) -> &str { + &self.name + } + pub fn backend(&self) -> &str { + self.backend.as_deref().unwrap_or(&self.name) + } + pub fn paths(&self) -> Option<&[String]> { + self.paths.as_deref() } fn try_from(plugin_name: &str, configs: &V) -> ZResult> { let configs = configs.as_object().ok_or_else(|| { diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 613eae97d0..8b6ffbe3ef 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -35,6 +35,7 @@ use zenoh::prelude::sync::*; use zenoh::runtime::Runtime; use zenoh::Session; use zenoh_backend_traits::CreateVolume; +use zenoh_backend_traits::VolumePlugin; use zenoh_backend_traits::CREATE_VOLUME_FN_NAME; use zenoh_backend_traits::{config::*, Volume}; use zenoh_core::zlock; @@ -72,14 +73,17 @@ impl Plugin for StoragesPlugin { )?))) } } + +type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; + struct StorageRuntime(Arc>); struct StorageRuntimeInner { name: String, runtime: Runtime, session: Arc, - lib_loader: LibLoader, volumes: HashMap, storages: HashMap>>, + plugins_manager: PluginsManager, } impl StorageRuntimeInner { fn status_key(&self) -> String { @@ -110,9 +114,9 @@ impl StorageRuntimeInner { name, runtime, session, - lib_loader, volumes: Default::default(), storages: Default::default(), + plugins_manager: PluginsManager::dynamic(lib_loader, BACKEND_LIB_PREFIX), }; new_self.spawn_volume(VolumeConfig { name: MEMORY_BACKEND_NAME.into(), @@ -153,51 +157,27 @@ impl StorageRuntimeInner { std::mem::drop(self.volumes.remove(&volume.name)); } fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { - let volume_id = config.name.clone(); - if volume_id == MEMORY_BACKEND_NAME { + let volume_id = config.name(); + let backend_name = config.backend(); + if backend_name == MEMORY_BACKEND_NAME { match create_memory_backend(config) { Ok(backend) => { self.volumes.insert( - volume_id, + volume_id.to_string(), VolumeHandle::new(backend, None, "".into()), ); } Err(e) => bail!("{}", e), } } else { - match config.backend_search_method() { - BackendSearchMethod::ByPaths(paths) => { - for path in paths { - unsafe { - if let Ok((lib, path)) = LibLoader::load_file(path) { - return self.loaded_backend_from_lib( - &volume_id, - config.clone(), - lib, - path, - ); - } - } - } - bail!( - "Failed to find a suitable library for volume {} from paths: {:?}", - volume_id, - paths - ); - } - BackendSearchMethod::ByName(backend_name) => unsafe { - let backend_filename = format!("{}{}", BACKEND_LIB_PREFIX, &backend_name); - if let Ok((lib, path)) = self.lib_loader.search_and_load(&backend_filename) { - self.loaded_backend_from_lib(&volume_id, config.clone(), lib, path)?; - } else { - bail!( - "Failed to find a suitable library for volume {} (was looking for {}<.so/.dll/.dylib>)", - volume_id, - &backend_filename - ); - } - }, - }; + if let Some(paths) = config.paths() { + self.plugins_manager + .load_plugin_by_paths(volume_id, paths)?; + } else { + self.plugins_manager + .load_plugin_by_backend_name(volume_id, backend_name)?; + } + if let Some() }; Ok(()) } diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index 3def07880d..96a5ec22dc 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -21,7 +21,7 @@ use zenoh_backend_traits::config::{StorageConfig, VolumeConfig}; use zenoh_backend_traits::*; use zenoh_result::ZResult; -pub fn create_memory_backend(config: VolumeConfig) -> ZResult> { +pub fn create_memory_backend(config: VolumeConfig) -> ZResult { Ok(Box::new(MemoryBackend { config })) } diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 1ca1320470..f8ec592715 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -16,30 +16,35 @@ use libloading::Library; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::path::PathBuf; -use vtable::{PluginVTable, PluginLoaderVersion, PLUGIN_LOADER_VERSION, Compatibility}; +use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; use zenoh_result::{bail, zerror, ZResult}; use zenoh_util::LibLoader; /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. pub struct PluginsManager { + default_lib_prefix: String, loader: Option, plugin_starters: Vec + Send + Sync>>, running_plugins: HashMap, } -impl PluginsManager { +impl + PluginsManager +{ /// Constructs a new plugin manager with dynamic library loading enabled. - pub fn dynamic(loader: LibLoader) -> Self { + pub fn dynamic>(loader: LibLoader, default_lib_prefix: S) -> Self { PluginsManager { + default_lib_prefix: default_lib_prefix.into(), loader: Some(loader), plugin_starters: Vec::new(), running_plugins: HashMap::new(), } } - /// Constructs a new plugin manager with dynamic library loading enabled. + /// Constructs a new plugin manager with dynamic library loading disabled. pub fn static_plugins_only() -> Self { PluginsManager { + default_lib_prefix: String::new(), loader: None, plugin_starters: Vec::new(), running_plugins: HashMap::new(), @@ -157,12 +162,20 @@ impl ZResult { + /// Tries to load a plugin with the name `defaukt_lib_prefix` + `backend_name` + `.so | .dll | .dylib` + /// in lib_loader's search paths. + pub fn load_plugin_by_backend_name, T1: AsRef>( + &mut self, + name: T, + backend_name: T1, + ) -> ZResult { + let name = name.as_ref(); + let backend_name = backend_name.as_ref(); let (lib, p) = match &mut self.loader { - Some(l) => unsafe { l.search_and_load(&format!("zenoh_plugin_{}", &name))? }, - None => bail!("Can't load dynamic plugin ` {}`, as dynamic loading is not enabled for this plugin manager.", name), + Some(l) => unsafe { l.search_and_load(&format!("{}{}", &self.default_lib_prefix, &backend_name))? }, + None => bail!("Can't load dynamic plugin `{}`, as dynamic loading is not enabled for this plugin manager.", &name), }; - let plugin = match Self::load_plugin(&name, lib, p.clone()) { + let plugin = match Self::load_plugin(name, lib, p.clone()) { Ok(p) => p, Err(e) => bail!("After loading `{:?}`: {}", &p, e), }; @@ -170,16 +183,18 @@ impl + std::fmt::Debug>( + /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) + pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( &mut self, - name: String, + name: T, paths: &[P], ) -> ZResult { + let name = name.as_ref(); for path in paths { let path = path.as_ref(); match unsafe { LibLoader::load_file(path) } { Ok((lib, p)) => { - let plugin = Self::load_plugin(&name, lib, p)?; + let plugin = Self::load_plugin(name, lib, p)?; let path = plugin.path().into(); self.plugin_starters.push(Box::new(plugin)); return Ok(path); @@ -228,8 +243,8 @@ where } } -impl PluginStarter - for DynamicPlugin +impl + PluginStarter for DynamicPlugin { fn name(&self) -> &str { &self.name @@ -252,20 +267,29 @@ pub struct DynamicPlugin DynamicPlugin { +impl + DynamicPlugin +{ fn new(name: String, lib: Library, path: PathBuf) -> ZResult { - let get_plugin_loader_version = unsafe { - lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? - }; + let get_plugin_loader_version = + unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; let plugin_loader_version = get_plugin_loader_version(); if plugin_loader_version != PLUGIN_LOADER_VERSION { - bail!("Plugin loader version mismatch: host = {}, plugin = {}", PLUGIN_LOADER_VERSION, plugin_loader_version); + bail!( + "Plugin loader version mismatch: host = {}, plugin = {}", + PLUGIN_LOADER_VERSION, + plugin_loader_version + ); } let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; let plugin_compatibility_record = get_compatibility(); let host_compatibility_record = Compatibility::new::(); if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { - bail!("Plugin compatibility mismatch:\nhost = {:?}\nplugin = {:?}\n", host_compatibility_record, plugin_compatibility_record); + bail!( + "Plugin compatibility mismatch:\nhost = {:?}\nplugin = {:?}\n", + host_compatibility_record, + plugin_compatibility_record + ); } // TODO: check loader version and compatibility diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index a71382dea2..329cca0e47 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -195,12 +195,13 @@ impl AdminSpace { plugins_mgr.stop(&plugin); } PluginDiff::Start(plugin) => { - let load = match &plugin.paths { - Some(paths) => { - plugins_mgr.load_plugin_by_paths(plugin.name.clone(), paths) - } - None => plugins_mgr.load_plugin_by_name(plugin.name.clone()), - }; + let load = + match &plugin.paths { + Some(paths) => plugins_mgr + .load_plugin_by_paths(plugin.name.clone(), paths), + None => plugins_mgr + .load_plugin_by_backend_name(plugin.name.clone()), + }; match load { Err(e) => { if plugin.required { diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 28df513a46..dc31a0d5bb 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -90,7 +90,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na req = if required { "required" } else { "" } ); if let Err(e) = match paths { - None => plugins.load_plugin_by_name(name.clone()), + None => plugins.load_plugin_by_backend_name(name.clone()), Some(paths) => plugins.load_plugin_by_paths(name.clone(), &paths), } { if required { From 684c279526f9960fd0950a495a0bdea97ae2ddb7 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 23 Oct 2023 16:30:54 +0200 Subject: [PATCH 020/106] replaced volumes map to plugin_manager --- plugins/example-storage-plugin/src/lib.rs | 2 +- plugins/zenoh-backend-traits/src/lib.rs | 2 +- .../src/backends_mgt.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 111 ++++-------------- .../src/memory_backend/mod.rs | 2 +- zenoh/src/net/runtime/adminspace.rs | 2 +- zenohd/src/main.rs | 4 +- 7 files changed, 30 insertions(+), 95 deletions(-) diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index a6d5d9760a..d0b9addafe 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -73,7 +73,7 @@ impl Volume for ExampleBackend { read_cost: 0, } } - async fn create_storage(&mut self, _props: StorageConfig) -> ZResult> { + async fn create_storage(&self, _props: StorageConfig) -> ZResult> { Ok(Box::::default()) } fn incoming_data_interceptor(&self) -> Option Sample + Send + Sync>> { diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 8ab5844de9..325e5a6981 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -204,7 +204,7 @@ pub trait Volume: Send + Sync { fn get_capability(&self) -> Capability; /// Creates a storage configured with some properties. - async fn create_storage(&mut self, props: StorageConfig) -> ZResult>; + async fn create_storage(&self, props: StorageConfig) -> ZResult>; /// Returns an interceptor that will be called before pushing any data /// into a storage created by this backend. `None` can be returned for no interception point. diff --git a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs index 981ec521ab..5fb37409fe 100644 --- a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs +++ b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs @@ -30,7 +30,7 @@ pub struct StoreIntercept { pub(crate) async fn create_and_start_storage( admin_key: String, config: StorageConfig, - backend: &mut Box, + backend: &Box, in_interceptor: Option Sample + Send + Sync>>, out_interceptor: Option Sample + Send + Sync>>, zenoh: Arc, diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 8b6ffbe3ef..161c0c70a6 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -21,12 +21,8 @@ use async_std::task; use flume::Sender; -use libloading::Library; -use memory_backend::create_memory_backend; use std::collections::HashMap; use std::convert::TryFrom; -use std::path::PathBuf; -use std::sync::atomic::AtomicBool; use std::sync::Arc; use std::sync::Mutex; use storages_mgt::StorageMessage; @@ -34,10 +30,7 @@ use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::sync::*; use zenoh::runtime::Runtime; use zenoh::Session; -use zenoh_backend_traits::CreateVolume; use zenoh_backend_traits::VolumePlugin; -use zenoh_backend_traits::CREATE_VOLUME_FN_NAME; -use zenoh_backend_traits::{config::*, Volume}; use zenoh_core::zlock; use zenoh_result::{bail, ZResult}; use zenoh_util::LibLoader; @@ -81,7 +74,6 @@ struct StorageRuntimeInner { name: String, runtime: Runtime, session: Arc, - volumes: HashMap, storages: HashMap>>, plugins_manager: PluginsManager, } @@ -114,7 +106,6 @@ impl StorageRuntimeInner { name, runtime, session, - volumes: Default::default(), storages: Default::default(), plugins_manager: PluginsManager::dynamic(lib_loader, BACKEND_LIB_PREFIX), }; @@ -136,7 +127,7 @@ impl StorageRuntimeInner { fn update>(&mut self, diffs: I) -> ZResult<()> { for diff in diffs { match diff { - ConfigDiff::DeleteVolume(volume) => self.kill_volume(volume), + ConfigDiff::DeleteVolume(volume) => self.kill_volume(&volume.name), ConfigDiff::AddVolume(volume) => { self.spawn_volume(volume)?; } @@ -146,29 +137,31 @@ impl StorageRuntimeInner { } Ok(()) } - fn kill_volume(&mut self, volume: VolumeConfig) { - if let Some(storages) = self.storages.remove(&volume.name) { + fn kill_volume>(&mut self, name: T) { + let name = name.as_ref(); + if let Some(storages) = self.storages.remove(name) { async_std::task::block_on(futures::future::join_all( storages .into_values() .map(|s| async move { s.send(StorageMessage::Stop) }), )); } - std::mem::drop(self.volumes.remove(&volume.name)); + self.plugins_manager.stop(name); } fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); if backend_name == MEMORY_BACKEND_NAME { - match create_memory_backend(config) { - Ok(backend) => { - self.volumes.insert( - volume_id.to_string(), - VolumeHandle::new(backend, None, "".into()), - ); - } - Err(e) => bail!("{}", e), - } + // match create_memory_backend(config) { + // Ok(backend) => { + // TODO: implement static memory backend as static plugin + // self.volumes.insert( + // volume_id.to_string(), + // VolumeHandle::new(backend, None, "".into()), + // ); + // } + // Err(e) => bail!("{}", e), + // } } else { if let Some(paths) = config.paths() { self.plugins_manager @@ -177,46 +170,10 @@ impl StorageRuntimeInner { self.plugins_manager .load_plugin_by_backend_name(volume_id, backend_name)?; } - if let Some() }; + self.plugins_manager.start(volume_id, &config)?; Ok(()) } - unsafe fn loaded_backend_from_lib( - &mut self, - volume_id: &str, - config: VolumeConfig, - lib: Library, - lib_path: PathBuf, - ) -> ZResult<()> { - if let Ok(create_backend) = lib.get::(CREATE_VOLUME_FN_NAME) { - match create_backend(config) { - Ok(backend) => { - self.volumes.insert( - volume_id.to_string(), - VolumeHandle::new( - backend, - Some(lib), - lib_path.to_string_lossy().into_owned(), - ), - ); - Ok(()) - } - Err(e) => bail!( - "Failed to load Backend {} from {}: {}", - volume_id, - lib_path.display(), - e - ), - } - } else { - bail!( - "Failed to instantiate volume {} from {}: function {}(VolumeConfig) not found in lib", - volume_id, - lib_path.display(), - String::from_utf8_lossy(CREATE_VOLUME_FN_NAME) - ); - } - } fn kill_storage(&mut self, config: StorageConfig) { let volume = &config.volume_id; if let Some(storages) = self.storages.get_mut(volume) { @@ -234,14 +191,14 @@ impl StorageRuntimeInner { fn spawn_storage(&mut self, storage: StorageConfig) -> ZResult<()> { let admin_key = self.status_key() + "/storages/" + &storage.name; let volume_id = storage.volume_id.clone(); - if let Some(backend) = self.volumes.get_mut(&volume_id) { + if let Some(backend) = self.plugins_manager.plugin(&volume_id) { let storage_name = storage.name.clone(); - let in_interceptor = backend.backend.incoming_data_interceptor(); - let out_interceptor = backend.backend.outgoing_data_interceptor(); + let in_interceptor = backend.incoming_data_interceptor(); + let out_interceptor = backend.outgoing_data_interceptor(); let stopper = async_std::task::block_on(create_and_start_storage( admin_key, storage, - &mut backend.backend, + &backend, in_interceptor, out_interceptor, self.session.clone(), @@ -259,28 +216,6 @@ impl StorageRuntimeInner { } } } -struct VolumeHandle { - backend: Box, - _lib: Option, - lib_path: String, - stopper: Arc, -} -impl VolumeHandle { - fn new(backend: Box, lib: Option, lib_path: String) -> Self { - VolumeHandle { - backend, - _lib: lib, - lib_path, - stopper: Arc::new(std::sync::atomic::AtomicBool::new(true)), - } - } -} -impl Drop for VolumeHandle { - fn drop(&mut self) { - self.stopper - .store(false, std::sync::atomic::Ordering::Relaxed); - } -} impl From for StorageRuntime { fn from(inner: StorageRuntimeInner) -> Self { StorageRuntime(Arc::new(Mutex::new(inner))) @@ -325,7 +260,7 @@ impl RunningPluginTrait for StorageRuntime { }); let guard = self.0.lock().unwrap(); with_extended_string(&mut key, &["/volumes/"], |key| { - for (volume_id, volume) in &guard.volumes { + for (volume_id, (lib_path, volume)) in guard.plugins_manager.running_plugins() { with_extended_string(key, &[volume_id], |key| { with_extended_string(key, &["/__path__"], |key| { if keyexpr::new(key.as_str()) @@ -334,7 +269,7 @@ impl RunningPluginTrait for StorageRuntime { { responses.push(zenoh::plugins::Response::new( key.clone(), - volume.lib_path.clone().into(), + lib_path.into(), )) } }); @@ -344,7 +279,7 @@ impl RunningPluginTrait for StorageRuntime { { responses.push(zenoh::plugins::Response::new( key.clone(), - volume.backend.get_admin_status(), + volume.get_admin_status(), )) } }); diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index 96a5ec22dc..5ac076ce0a 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -43,7 +43,7 @@ impl Volume for MemoryBackend { } } - async fn create_storage(&mut self, properties: StorageConfig) -> ZResult> { + async fn create_storage(&self, properties: StorageConfig) -> ZResult> { log::debug!("Create Memory Storage with configuration: {:?}", properties); Ok(Box::new(MemoryStorage::new(properties).await?)) } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 329cca0e47..de264502c0 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -200,7 +200,7 @@ impl AdminSpace { Some(paths) => plugins_mgr .load_plugin_by_paths(plugin.name.clone(), paths), None => plugins_mgr - .load_plugin_by_backend_name(plugin.name.clone()), + .load_plugin_by_backend_name(&plugin.name, &plugin.name), }; match load { Err(e) => { diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index dc31a0d5bb..aadab85552 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -76,7 +76,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na let config = config_from_args(&args); log::info!("Initial conf: {}", &config); - let mut plugins = PluginsManager::dynamic(config.libloader()); + let mut plugins = PluginsManager::dynamic(config.libloader(), "zenoh_plugin_"); // Static plugins are to be added here, with `.add_static::()` let mut required_plugins = HashSet::new(); for plugin_load in config.plugins().load_requests() { @@ -90,7 +90,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na req = if required { "required" } else { "" } ); if let Err(e) = match paths { - None => plugins.load_plugin_by_backend_name(name.clone()), + None => plugins.load_plugin_by_backend_name(&name, &name), Some(paths) => plugins.load_plugin_by_paths(name.clone(), &paths), } { if required { From 3f23cbca523ff3a81e2fb8edd73780cb13d67a2b Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 23 Oct 2023 17:15:20 +0200 Subject: [PATCH 021/106] static memory unfinihed --- .../zenoh-plugin-storage-manager/src/lib.rs | 31 +++++++------------ .../src/memory_backend/mod.rs | 14 +++++++++ plugins/zenoh-plugin-trait/src/loading.rs | 3 ++ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 161c0c70a6..497ddd48ac 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -21,6 +21,7 @@ use async_std::task; use flume::Sender; +use memory_backend::MemoryBackend; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::Arc; @@ -102,12 +103,15 @@ impl StorageRuntimeInner { .unwrap_or_default(); let session = Arc::new(zenoh::init(runtime.clone()).res_sync().unwrap()); + + let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX).add_static::(); + let mut new_self = StorageRuntimeInner { name, runtime, session, storages: Default::default(), - plugins_manager: PluginsManager::dynamic(lib_loader, BACKEND_LIB_PREFIX), + plugins_manager }; new_self.spawn_volume(VolumeConfig { name: MEMORY_BACKEND_NAME.into(), @@ -151,26 +155,13 @@ impl StorageRuntimeInner { fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); - if backend_name == MEMORY_BACKEND_NAME { - // match create_memory_backend(config) { - // Ok(backend) => { - // TODO: implement static memory backend as static plugin - // self.volumes.insert( - // volume_id.to_string(), - // VolumeHandle::new(backend, None, "".into()), - // ); - // } - // Err(e) => bail!("{}", e), - // } + if let Some(paths) = config.paths() { + self.plugins_manager + .load_plugin_by_paths(volume_id, paths)?; } else { - if let Some(paths) = config.paths() { - self.plugins_manager - .load_plugin_by_paths(volume_id, paths)?; - } else { - self.plugins_manager - .load_plugin_by_backend_name(volume_id, backend_name)?; - } - }; + self.plugins_manager + .load_plugin_by_backend_name(volume_id, backend_name)?; + } self.plugins_manager.start(volume_id, &config)?; Ok(()) } diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index 5ac076ce0a..17927c40cf 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -13,6 +13,7 @@ // use async_std::sync::RwLock; use async_trait::async_trait; +use zenoh_plugin_trait::Plugin; use std::collections::HashMap; use std::sync::Arc; use zenoh::prelude::r#async::*; @@ -21,6 +22,8 @@ use zenoh_backend_traits::config::{StorageConfig, VolumeConfig}; use zenoh_backend_traits::*; use zenoh_result::ZResult; +use crate::MEMORY_BACKEND_NAME; + pub fn create_memory_backend(config: VolumeConfig) -> ZResult { Ok(Box::new(MemoryBackend { config })) } @@ -29,6 +32,17 @@ pub struct MemoryBackend { config: VolumeConfig, } +impl Plugin for MemoryBackend { + type StartArgs = VolumeConfig; + type RunningPlugin = VolumePlugin; + + const STATIC_NAME: &'static str = MEMORY_BACKEND_NAME; + + fn start(name: &str, args: &Self::StartArgs) -> ZResult { + todo!() + } +} + #[async_trait] impl Volume for MemoryBackend { fn get_admin_status(&self) -> serde_json::Value { diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index f8ec592715..614064aace 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -170,6 +170,9 @@ impl ZResult { let name = name.as_ref(); + + // TODO: check if plugin is already loaded + let backend_name = backend_name.as_ref(); let (lib, p) = match &mut self.loader { Some(l) => unsafe { l.search_and_load(&format!("{}{}", &self.default_lib_prefix, &backend_name))? }, From 41f5216f21c2b3e6f556f4c09105b4a3b628b179 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 24 Oct 2023 18:10:11 +0200 Subject: [PATCH 022/106] plugin manager refactor --- plugins/zenoh-plugin-trait/src/loading.rs | 251 +++++++++++++--------- 1 file changed, 146 insertions(+), 105 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 614064aace..be5a11388b 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -13,20 +13,69 @@ // use crate::*; use libloading::Library; -use std::collections::hash_map::Entry; -use std::collections::HashMap; use std::path::PathBuf; use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; -use zenoh_result::{bail, zerror, ZResult}; +use zenoh_result::{bail, ZResult}; use zenoh_util::LibLoader; +struct PluginInstance { + starter: Box + Send + Sync>, + running_plugin: Option, +} + +impl PluginInfo + for PluginInstance +{ + fn name(&self) -> &str { + self.starter.name() + } + fn path(&self) -> &str { + self.starter.path() + } + fn deletable(&self) -> bool { + self.starter.deletable() + } +} + +impl + PluginInstance +{ + fn new + Send + Sync + 'static>(starter: T) -> Self { + Self { + starter: Box::new(starter), + running_plugin: None, + } + } + fn get_running_plugin(&self) -> Option<&RunningPlugin> { + self.running_plugin.as_ref() + } + fn stop(&mut self) -> bool { + if self.running_plugin.is_some() { + self.running_plugin = None; + true + } else { + false + } + } + fn start(&mut self, args: &StartArgs) -> ZResult<(bool, &RunningPlugin)> { + if self.running_plugin.is_some() { + return Ok((false, self.running_plugin.as_ref().unwrap())); + } + let plugin = self.starter.start(args)?; + self.running_plugin = Some(plugin); + Ok((true, self.running_plugin.as_ref().unwrap())) + } + fn as_plugin_info(&self) -> &dyn PluginInfo { + self + } +} + /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. pub struct PluginsManager { default_lib_prefix: String, loader: Option, - plugin_starters: Vec + Send + Sync>>, - running_plugins: HashMap, + plugins: Vec>, } impl @@ -37,8 +86,7 @@ impl Self { let plugin_starter: StaticPlugin

= StaticPlugin::new(); - self.plugin_starters.push(Box::new(plugin_starter)); + self.plugins.push(PluginInstance::new(plugin_starter)); self } - /// Starts `plugin`. - /// - /// `Ok(true)` => plugin was successfully started - /// `Ok(false)` => plugin was running already, nothing happened - /// `Err(e)` => starting the plugin failed due to `e` - pub fn start( + fn get_plugin_instance_mut( &mut self, - plugin: &str, - args: &StartArgs, - ) -> ZResult> { - match self.running_plugins.entry(plugin.into()) { - Entry::Occupied(_) => Ok(None), - Entry::Vacant(e) => { - match self.plugin_starters.iter().find(|p| p.name() == plugin) { - Some(s) => { - let path = s.path(); - let (_, plugin) = e.insert((path.into(), s.start(args).map_err(|e| zerror!(e => "Failed to load plugin {} (from {})", plugin, path))?)); - Ok(Some((path, &*plugin))) - } - None => bail!("Plugin starter for `{}` not found", plugin), - } - } - } + name: &str, + ) -> Option<&mut PluginInstance> { + self.plugins.iter_mut().find(|p| p.name() == name) } - /// Lazily starts all plugins. - /// - /// `Ok(Ok(name))` => plugin `name` was successfully started - /// `Ok(Err(name))` => plugin `name` wasn't started because it was already running - /// `Err(e)` => Error `e` occured when trying to start plugin `name` - pub fn start_all<'l>( - &'l mut self, - args: &'l StartArgs, - ) -> impl Iterator>)> + 'l { - let PluginsManager { - plugin_starters, - running_plugins, - .. - } = self; - plugin_starters.iter().map(move |p| { - let name = p.name(); - let path = p.path(); - ( - name, - path, - match running_plugins.entry(name.into()) { - std::collections::hash_map::Entry::Occupied(_) => Ok(None), - std::collections::hash_map::Entry::Vacant(e) => match p.start(args) { - Ok(p) => Ok(Some(unsafe { - std::mem::transmute(&e.insert((path.into(), p)).1) - })), - Err(e) => Err(e), - }, - }, - ) - }) + fn get_plugin_instance( + &mut self, + name: &str, + ) -> Option<&PluginInstance> { + self.plugins.iter().find(|p| p.name() == name) + } + + fn get_plugin_instance_mut_err( + &mut self, + name: &str, + ) -> ZResult<&mut PluginInstance> { + self.get_plugin_instance_mut(name) + .ok_or_else(|| format!("Plugin `{}` not found", name).into()) + } + + fn get_plugin_instance_err( + &mut self, + name: &str, + ) -> ZResult<&PluginInstance> { + self.get_plugin_instance(name) + .ok_or_else(|| format!("Plugin `{}` not found", name).into()) + } + + /// Starts plugin named `name` + /// Returns + /// Ok((true, &RunningPluguin)) => plugin was successfully started + /// Ok((false, &RunningPlugin)) => plugin was already running + /// Err(e) => starting the plugin failed due to `e` + pub fn start(&mut self, name: &str, args: &StartArgs) -> ZResult<(bool, &RunningPlugin)> { + self.get_plugin_instance_mut_err(name)?.start(args) } /// Stops `plugin`, returning `true` if it was indeed running. - pub fn stop(&mut self, plugin: &str) -> bool { - let result = self.running_plugins.remove(plugin).is_some(); - self.plugin_starters - .retain(|p| p.name() != plugin || !p.deletable()); - result + pub fn stop(&mut self, name: &str) -> ZResult { + Ok(self.get_plugin_instance_mut_err(name)?.stop()) } /// Lists the loaded plugins by name. - pub fn loaded_plugins(&self) -> impl Iterator { - self.plugin_starters.iter().map(|p| p.name()) - } - /// Retuns a map containing each running plugin's load-path, associated to its name. - pub fn running_plugins_info(&self) -> HashMap<&str, &str> { - let mut result = HashMap::with_capacity(self.running_plugins.len()); - for p in self.plugin_starters.iter() { - let name = p.name(); - if self.running_plugins.contains_key(name) && !result.contains_key(name) { - result.insert(name, p.path()); - } - } - result + pub fn plugins(&self) -> impl Iterator)> { + self.plugins + .iter() + .map(|p| (p.as_plugin_info(), p.get_running_plugin())) } /// Returns an iterator over each running plugin, where the keys are their name, and the values are a tuple of their path and handle. - pub fn running_plugins(&self) -> impl Iterator { - self.running_plugins + pub fn running_plugins(&self) -> impl Iterator { + self.plugins .iter() - .map(|(s, (path, p))| (s.as_str(), (path.as_str(), p))) + .filter_map(|p| p.get_running_plugin().map(|rp| (p.as_plugin_info(), rp))) } /// Returns the handle of the requested running plugin if available. pub fn plugin(&self, name: &str) -> Option<&RunningPlugin> { - self.running_plugins.get(name).map(|p| &p.1) + self.plugins + .iter() + .find(|p| p.name() == name) + .and_then(|p| p.get_running_plugin()) } fn load_plugin( @@ -168,11 +187,11 @@ impl ZResult { + ) -> ZResult<&dyn PluginInfo> { let name = name.as_ref(); - - // TODO: check if plugin is already loaded - + if self.get_plugin_instance(name).is_some() { + bail!("Plugin `{}` already loaded", name); + } let backend_name = backend_name.as_ref(); let (lib, p) = match &mut self.loader { Some(l) => unsafe { l.search_and_load(&format!("{}{}", &self.default_lib_prefix, &backend_name))? }, @@ -182,25 +201,26 @@ impl p, Err(e) => bail!("After loading `{:?}`: {}", &p, e), }; - let path = plugin.path().into(); - self.plugin_starters.push(Box::new(plugin)); - Ok(path) + self.plugins.push(PluginInstance::new(plugin)); + Ok(self.plugins.last().unwrap().as_plugin_info()) } /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( &mut self, name: T, paths: &[P], - ) -> ZResult { + ) -> ZResult<&dyn PluginInfo> { let name = name.as_ref(); + if self.get_plugin_instance(name).is_some() { + bail!("Plugin `{}` already loaded", name); + } for path in paths { let path = path.as_ref(); match unsafe { LibLoader::load_file(path) } { Ok((lib, p)) => { let plugin = Self::load_plugin(name, lib, p)?; - let path = plugin.path().into(); - self.plugin_starters.push(Box::new(plugin)); - return Ok(path); + self.plugins.push(PluginInstance::new(plugin)); + return Ok(self.plugins.last().unwrap().as_plugin_info()); } Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), } @@ -209,13 +229,17 @@ impl { +pub trait PluginInfo { fn name(&self) -> &str; fn path(&self) -> &str; - fn start(&self, args: &StartArgs) -> ZResult; fn deletable(&self) -> bool; } +trait PluginStarter: PluginInfo { + fn start(&self, args: &StartArgs) -> ZResult; + fn as_plugin_info(&self) -> &dyn PluginInfo; +} + struct StaticPlugin

{ inner: std::marker::PhantomData

, } @@ -228,7 +252,7 @@ impl

StaticPlugin

{ } } -impl PluginStarter for StaticPlugin

+impl PluginInfo for StaticPlugin

where P: Plugin, { @@ -238,16 +262,25 @@ where fn path(&self) -> &str { "" } + fn deletable(&self) -> bool { + false + } +} + +impl PluginStarter for StaticPlugin

+where + P: Plugin, +{ fn start(&self, args: &StartArgs) -> ZResult { P::start(P::STATIC_NAME, args) } - fn deletable(&self) -> bool { - false + fn as_plugin_info(&self) -> &dyn PluginInfo { + self } } -impl - PluginStarter for DynamicPlugin +impl PluginInfo + for DynamicPlugin { fn name(&self) -> &str { &self.name @@ -255,11 +288,19 @@ impl fn path(&self) -> &str { self.path.to_str().unwrap() } + fn deletable(&self) -> bool { + true + } +} + +impl + PluginStarter for DynamicPlugin +{ fn start(&self, args: &StartArgs) -> ZResult { (self.vtable.start)(self.name(), args) } - fn deletable(&self) -> bool { - true + fn as_plugin_info(&self) -> &dyn PluginInfo { + self } } From 84498a472a3d44903b86d3aa2024744a485c7856 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 25 Oct 2023 23:45:50 +0200 Subject: [PATCH 023/106] plugin manager api update --- plugins/zenoh-plugin-trait/src/loading.rs | 116 +++++++++++----------- zenoh/src/net/runtime/adminspace.rs | 102 ++++++++++--------- 2 files changed, 114 insertions(+), 104 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index be5a11388b..dba53c2328 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -57,13 +57,13 @@ impl false } } - fn start(&mut self, args: &StartArgs) -> ZResult<(bool, &RunningPlugin)> { + fn start(&mut self, args: &StartArgs) -> ZResult { if self.running_plugin.is_some() { - return Ok((false, self.running_plugin.as_ref().unwrap())); + return Ok(false); } let plugin = self.starter.start(args)?; self.running_plugin = Some(plugin); - Ok((true, self.running_plugin.as_ref().unwrap())) + Ok(true) } fn as_plugin_info(&self) -> &dyn PluginInfo { self @@ -78,6 +78,13 @@ pub struct PluginsManager>, } +/// Unique identifier of plugin in plugin manager. Actually is just an index in the plugins list. +/// It's guaranteed that if intex is obtained from plugin manager, it's valid for this plugin manager. +/// (at least at this moment, when there is no pluing unload support). +/// Using it instead of plugin name allows to avoid checking for ``Option`` every time. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct PluginIndex(usize); + impl PluginsManager { @@ -109,68 +116,63 @@ impl Option<&mut PluginInstance> { - self.plugins.iter_mut().find(|p| p.name() == name) - } - - fn get_plugin_instance( - &mut self, - name: &str, - ) -> Option<&PluginInstance> { - self.plugins.iter().find(|p| p.name() == name) + /// Returns `true` if the plugin with the given index exists in the manager. + pub fn check_plugin_index(&self, index: PluginIndex) -> bool { + index.0 < self.plugins.len() } - fn get_plugin_instance_mut_err( - &mut self, - name: &str, - ) -> ZResult<&mut PluginInstance> { - self.get_plugin_instance_mut(name) - .ok_or_else(|| format!("Plugin `{}` not found", name).into()) + /// Returns plugin index by name + pub fn get_plugin_index(&self, name: &str) -> Option { + self.plugins + .iter() + .position(|p| p.name() == name) + .map(PluginIndex) } - fn get_plugin_instance_err( - &mut self, - name: &str, - ) -> ZResult<&PluginInstance> { - self.get_plugin_instance(name) + /// Returns plugin index by name or error if plugin not found + pub fn get_plugin_index_err(&self, name: &str) -> ZResult { + self.get_plugin_index(name) .ok_or_else(|| format!("Plugin `{}` not found", name).into()) } - /// Starts plugin named `name` + /// Starts plugin. /// Returns - /// Ok((true, &RunningPluguin)) => plugin was successfully started - /// Ok((false, &RunningPlugin)) => plugin was already running + /// Ok(true) => plugin was successfully started + /// Ok(false) => plugin was already running /// Err(e) => starting the plugin failed due to `e` - pub fn start(&mut self, name: &str, args: &StartArgs) -> ZResult<(bool, &RunningPlugin)> { - self.get_plugin_instance_mut_err(name)?.start(args) + pub fn start(&mut self, index: PluginIndex, args: &StartArgs) -> ZResult { + let instance = &mut self.plugins[index.0]; + let already_started = instance.start(args)?; + Ok(already_started) } /// Stops `plugin`, returning `true` if it was indeed running. - pub fn stop(&mut self, name: &str) -> ZResult { - Ok(self.get_plugin_instance_mut_err(name)?.stop()) - } - - /// Lists the loaded plugins by name. - pub fn plugins(&self) -> impl Iterator)> { - self.plugins - .iter() - .map(|p| (p.as_plugin_info(), p.get_running_plugin())) + pub fn stop(&mut self, index: PluginIndex) -> ZResult { + let instance = &mut self.plugins[index.0]; + let was_running = instance.stop(); + Ok(was_running) + } + /// Lists the loaded plugins + pub fn plugins(&self) -> impl Iterator + '_ { + self.plugins.iter().enumerate().map(|(i, _)| PluginIndex(i)) + } + /// Lists the loaded plugins + pub fn running_plugins(&self) -> impl Iterator + '_ { + self.plugins.iter().enumerate().filter_map(|(i, p)| { + if p.get_running_plugin().is_some() { + Some(PluginIndex(i)) + } else { + None + } + }) } - /// Returns an iterator over each running plugin, where the keys are their name, and the values are a tuple of their path and handle. - pub fn running_plugins(&self) -> impl Iterator { - self.plugins - .iter() - .filter_map(|p| p.get_running_plugin().map(|rp| (p.as_plugin_info(), rp))) + /// Returns running plugin interface of plugin or none if plugin is stopped + pub fn running_plugin(&self, index: PluginIndex) -> Option<&RunningPlugin> { + self.plugins[index.0].get_running_plugin() } - /// Returns the handle of the requested running plugin if available. - pub fn plugin(&self, name: &str) -> Option<&RunningPlugin> { - self.plugins - .iter() - .find(|p| p.name() == name) - .and_then(|p| p.get_running_plugin()) + /// Returns plugin information + pub fn plugin(&self, index: PluginIndex) -> &dyn PluginInfo { + self.plugins[index.0].as_plugin_info() } fn load_plugin( @@ -187,9 +189,9 @@ impl ZResult<&dyn PluginInfo> { + ) -> ZResult { let name = name.as_ref(); - if self.get_plugin_instance(name).is_some() { + if self.get_plugin_index(name).is_some() { bail!("Plugin `{}` already loaded", name); } let backend_name = backend_name.as_ref(); @@ -202,16 +204,16 @@ impl bail!("After loading `{:?}`: {}", &p, e), }; self.plugins.push(PluginInstance::new(plugin)); - Ok(self.plugins.last().unwrap().as_plugin_info()) + Ok(PluginIndex(self.plugins.len() - 1)) } /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( &mut self, name: T, paths: &[P], - ) -> ZResult<&dyn PluginInfo> { + ) -> ZResult { let name = name.as_ref(); - if self.get_plugin_instance(name).is_some() { + if self.get_plugin_index(name).is_some() { bail!("Plugin `{}` already loaded", name); } for path in paths { @@ -220,7 +222,7 @@ impl { let plugin = Self::load_plugin(name, lib, p)?; self.plugins.push(PluginInstance::new(plugin)); - return Ok(self.plugins.last().unwrap().as_plugin_info()); + return Ok(PluginIndex(self.plugins.len() - 1)); } Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index de264502c0..f28aa0faf5 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -73,8 +73,12 @@ impl ConfigValidator for AdminSpace { new: &serde_json::Map, ) -> ZResult>> { let plugins_mgr = zlock!(self.context.plugins_mgr); - if let Some(plugin) = plugins_mgr.plugin(name) { - plugin.config_checker(path, current, new) + if let Some(plugin) = plugins_mgr.get_plugin_index(name) { + if let Some(plugin) = plugins_mgr.running_plugin(plugin) { + plugin.config_checker(path, current, new) + } else { + Err(format!("Plugin {name} not running").into()) + } } else { Err(format!("Plugin {name} not found").into()) } @@ -125,9 +129,11 @@ impl AdminSpace { ); let mut active_plugins = plugins_mgr - .running_plugins_info() - .into_iter() - .map(|(a, b)| (a.to_string(), b.to_string())) + .running_plugins() + .map(|index| { + let info = plugins_mgr.plugin(index); + (info.name().to_string(), info.path().to_string()) + }) .collect::>(); let context = Arc::new(AdminContext { @@ -190,46 +196,43 @@ impl AdminSpace { let mut plugins_mgr = zlock!(admin.context.plugins_mgr); for diff in diffs { match diff { - PluginDiff::Delete(plugin) => { - active_plugins.remove(plugin.as_str()); - plugins_mgr.stop(&plugin); + PluginDiff::Delete(name) => { + active_plugins.remove(name.as_str()); + if let Some(index) = plugins_mgr.get_plugin_index(&name) { + let _ = plugins_mgr.stop(index); + } } PluginDiff::Start(plugin) => { - let load = - match &plugin.paths { - Some(paths) => plugins_mgr - .load_plugin_by_paths(plugin.name.clone(), paths), - None => plugins_mgr - .load_plugin_by_backend_name(&plugin.name, &plugin.name), - }; - match load { - Err(e) => { - if plugin.required { - panic!("Failed to load plugin `{}`: {}", plugin.name, e) - } else { - log::error!( - "Failed to load plugin `{}`: {}", - plugin.name, - e - ) - } + let name = &plugin.name; + if let Ok(index) = match &plugin.paths { + Some(paths) => plugins_mgr.load_plugin_by_paths(name, paths), + None => { + plugins_mgr.load_plugin_by_backend_name(name, &plugin.name) } - Ok(path) => { - let name = &plugin.name; - log::info!("Loaded plugin `{}` from {}", name, &path); - match plugins_mgr.start(name, &admin.context.runtime) { - Ok(Some((path, _))) => { - active_plugins.insert(name.into(), path.into()); - log::info!( - "Successfully started plugin `{}` from {}", - name, - path - ); - } - Ok(None) => { - log::warn!("Plugin `{}` was already running", name) - } - Err(e) => log::error!("{}", e), + } + .map_err(|e| { + if plugin.required { + panic!("Failed to load plugin `{}`: {}", name, e) + } else { + log::error!("Failed to load plugin `{}`: {}", name, e) + } + }) { + let path = plugins_mgr.plugin(index).path().to_string(); + log::info!("Loaded plugin `{}` from {}", name, path); + match plugins_mgr.start(index, &admin.context.runtime) { + Ok(true) => { + active_plugins.insert(name.into(), path.clone()); + log::info!( + "Successfully started plugin `{}` from {}", + name, + path + ); + } + Ok(false) => { + log::warn!("Plugin `{}` was already running", name) + } + Err(e) => { + log::error!("Failed to start plugin `{}`: {}", name, e) } } } @@ -430,10 +433,11 @@ fn router_data(context: &AdminContext, query: Query) { // plugins info let plugins: serde_json::Value = { - zlock!(context.plugins_mgr) - .running_plugins_info() - .into_iter() - .map(|(k, v)| (k, json!({ "path": v }))) + let plugins_mgr = zlock!(context.plugins_mgr); + plugins_mgr + .running_plugins() + .map(|index| plugins_mgr.plugin(index)) + .map(|info| (info.name(), json!({ "path": info.path() }))) .collect() }; @@ -637,7 +641,11 @@ fn plugins_status(context: &AdminContext, query: Query) { let guard = zlock!(context.plugins_mgr); let mut root_key = format!("@/router/{}/status/plugins/", &context.zid_str); - for (name, (path, plugin)) in guard.running_plugins() { + for index in guard.running_plugins() { + let info = guard.plugin(index); + let name = info.name(); + let path = info.path(); + let plugin = guard.running_plugin(index).unwrap(); with_extended_string(&mut root_key, &[name], |plugin_key| { with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { if let Ok(key_expr) = KeyExpr::try_from(plugin_path_key.clone()) { From ef7bfaa484eb174813010a12a4dc64c3f27c23b0 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 26 Oct 2023 10:30:25 +0200 Subject: [PATCH 024/106] running plugin index added --- plugins/zenoh-plugin-trait/src/loading.rs | 72 ++++++++++++++++----- zenoh/src/net/runtime/adminspace.rs | 79 ++++++++++++----------- 2 files changed, 97 insertions(+), 54 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index dba53c2328..155045e13a 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -85,6 +85,29 @@ pub struct PluginsManager PluginIndex; +} + +impl PluginIndexTrait for PluginIndex { + fn index(&self) -> PluginIndex { + *self + } +} + +impl PluginIndexTrait for RunningPluginIndex { + fn index(&self) -> PluginIndex { + self.0 + } +} + impl PluginsManager { @@ -117,8 +140,8 @@ impl bool { - index.0 < self.plugins.len() + pub fn check_plugin_index(&self, index: T) -> bool { + index.index().0 < self.plugins.len() } /// Returns plugin index by name @@ -135,20 +158,39 @@ impl Option { + self.get_plugin_index(name).and_then(|i| { + self.plugins[i.0] + .get_running_plugin() + .map(|_| RunningPluginIndex(i)) + }) + } + + /// Returns running plugin index by name or error if plugin not found + pub fn get_running_plugin_index_err(&self, name: &str) -> ZResult { + self.get_running_plugin_index(name) + .ok_or_else(|| format!("Plugin `{}` not running", name).into()) + } + /// Starts plugin. /// Returns - /// Ok(true) => plugin was successfully started - /// Ok(false) => plugin was already running + /// Ok(true, index) => plugin was successfully started + /// Ok(false, index) => plugin was already running /// Err(e) => starting the plugin failed due to `e` - pub fn start(&mut self, index: PluginIndex, args: &StartArgs) -> ZResult { - let instance = &mut self.plugins[index.0]; + pub fn start( + &mut self, + index: T, + args: &StartArgs, + ) -> ZResult<(bool, RunningPluginIndex)> { + let instance = &mut self.plugins[index.index().0]; let already_started = instance.start(args)?; - Ok(already_started) + Ok((already_started, RunningPluginIndex(index.index()))) } /// Stops `plugin`, returning `true` if it was indeed running. - pub fn stop(&mut self, index: PluginIndex) -> ZResult { - let instance = &mut self.plugins[index.0]; + pub fn stop(&mut self, index: RunningPluginIndex) -> ZResult { + let instance = &mut self.plugins[index.index().0]; let was_running = instance.stop(); Ok(was_running) } @@ -157,22 +199,22 @@ impl impl Iterator + '_ { + pub fn running_plugins(&self) -> impl Iterator + '_ { self.plugins.iter().enumerate().filter_map(|(i, p)| { if p.get_running_plugin().is_some() { - Some(PluginIndex(i)) + Some(RunningPluginIndex(PluginIndex(i))) } else { None } }) } /// Returns running plugin interface of plugin or none if plugin is stopped - pub fn running_plugin(&self, index: PluginIndex) -> Option<&RunningPlugin> { - self.plugins[index.0].get_running_plugin() + pub fn running_plugin(&self, index: RunningPluginIndex) -> &RunningPlugin { + self.plugins[index.index().0].get_running_plugin().unwrap() } /// Returns plugin information - pub fn plugin(&self, index: PluginIndex) -> &dyn PluginInfo { - self.plugins[index.0].as_plugin_info() + pub fn plugin(&self, index: T) -> &dyn PluginInfo { + self.plugins[index.index().0].as_plugin_info() } fn load_plugin( diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index f28aa0faf5..6f09c98d7c 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -73,15 +73,10 @@ impl ConfigValidator for AdminSpace { new: &serde_json::Map, ) -> ZResult>> { let plugins_mgr = zlock!(self.context.plugins_mgr); - if let Some(plugin) = plugins_mgr.get_plugin_index(name) { - if let Some(plugin) = plugins_mgr.running_plugin(plugin) { - plugin.config_checker(path, current, new) - } else { - Err(format!("Plugin {name} not running").into()) - } - } else { - Err(format!("Plugin {name} not found").into()) - } + let index = plugins_mgr.get_running_plugin_index_err(name)?; + plugins_mgr + .running_plugin(index) + .config_checker(path, current, new) } } @@ -198,41 +193,47 @@ impl AdminSpace { match diff { PluginDiff::Delete(name) => { active_plugins.remove(name.as_str()); - if let Some(index) = plugins_mgr.get_plugin_index(&name) { + if let Some(index) = plugins_mgr.get_running_plugin_index(&name) { let _ = plugins_mgr.stop(index); } } PluginDiff::Start(plugin) => { let name = &plugin.name; - if let Ok(index) = match &plugin.paths { - Some(paths) => plugins_mgr.load_plugin_by_paths(name, paths), - None => { - plugins_mgr.load_plugin_by_backend_name(name, &plugin.name) - } - } - .map_err(|e| { - if plugin.required { - panic!("Failed to load plugin `{}`: {}", name, e) - } else { - log::error!("Failed to load plugin `{}`: {}", name, e) - } - }) { - let path = plugins_mgr.plugin(index).path().to_string(); - log::info!("Loaded plugin `{}` from {}", name, path); - match plugins_mgr.start(index, &admin.context.runtime) { - Ok(true) => { - active_plugins.insert(name.into(), path.clone()); - log::info!( - "Successfully started plugin `{}` from {}", - name, - path - ); + let index = if let Some(paths) = &plugin.paths { + plugins_mgr.load_plugin_by_paths(name, paths) + } else { + plugins_mgr.load_plugin_by_backend_name(name, &plugin.name) + }; + match index { + Ok(index) => { + let path = plugins_mgr.plugin(index).path().to_string(); + log::info!("Loaded plugin `{}` from {}", name, path); + match plugins_mgr.start(index, &admin.context.runtime) { + Ok((true, _)) => { + active_plugins.insert(name.into(), path.clone()); + log::info!( + "Successfully started plugin `{}` from {}", + name, + path + ); + } + Ok((false, _)) => { + log::warn!("Plugin `{}` was already running", name) + } + Err(e) => { + log::error!( + "Failed to start plugin `{}`: {}", + name, + e + ) + } } - Ok(false) => { - log::warn!("Plugin `{}` was already running", name) - } - Err(e) => { - log::error!("Failed to start plugin `{}`: {}", name, e) + } + Err(e) => { + if plugin.required { + panic!("Failed to load plugin `{}`: {}", name, e) + } else { + log::error!("Failed to load plugin `{}`: {}", name, e) } } } @@ -645,7 +646,7 @@ fn plugins_status(context: &AdminContext, query: Query) { let info = guard.plugin(index); let name = info.name(); let path = info.path(); - let plugin = guard.running_plugin(index).unwrap(); + let plugin = guard.running_plugin(index); with_extended_string(&mut root_key, &[name], |plugin_key| { with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { if let Ok(key_expr) = KeyExpr::try_from(plugin_path_key.clone()) { From 7d4856b1ef7f8deaea9a24c4506eee2797169ac0 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 27 Oct 2023 13:39:48 +0200 Subject: [PATCH 025/106] safer plugin load api, unfinished --- plugins/zenoh-plugin-trait/src/loading.rs | 249 +++++++++++----------- zenoh/src/net/runtime/adminspace.rs | 42 ++-- zenohd/src/main.rs | 11 + 3 files changed, 154 insertions(+), 148 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 155045e13a..45fe71d8d5 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -18,27 +18,13 @@ use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VER use zenoh_result::{bail, ZResult}; use zenoh_util::LibLoader; -struct PluginInstance { +pub struct PluginRecord { starter: Box + Send + Sync>, running_plugin: Option, } -impl PluginInfo - for PluginInstance -{ - fn name(&self) -> &str { - self.starter.name() - } - fn path(&self) -> &str { - self.starter.path() - } - fn deletable(&self) -> bool { - self.starter.deletable() - } -} - impl - PluginInstance + PluginRecord { fn new + Send + Sync + 'static>(starter: T) -> Self { Self { @@ -46,66 +32,82 @@ impl running_plugin: None, } } - fn get_running_plugin(&self) -> Option<&RunningPlugin> { - self.running_plugin.as_ref() - } - fn stop(&mut self) -> bool { + pub fn running(&self) -> Option<&dyn RunningPluginRecord> { if self.running_plugin.is_some() { - self.running_plugin = None; - true + Some(self) } else { - false + None } } - fn start(&mut self, args: &StartArgs) -> ZResult { + pub fn running_mut( + &mut self, + ) -> Option<&mut dyn RunningPluginRecord> { if self.running_plugin.is_some() { - return Ok(false); + Some(self) + } else { + None } - let plugin = self.starter.start(args)?; - self.running_plugin = Some(plugin); - Ok(true) } - fn as_plugin_info(&self) -> &dyn PluginInfo { - self + pub fn start( + &mut self, + args: &StartArgs, + ) -> ZResult<(bool, &mut dyn RunningPluginRecord)> { + let already_running = self.running_plugin.is_some(); + if !already_running { + self.running_plugin = Some(self.starter.start(args)?); + } + Ok((already_running, self)) + } + pub fn name(&self) -> &str { + self.starter.name() + } + pub fn path(&self) -> &str { + self.starter.path() + } + pub fn deletable(&self) -> bool { + self.starter.deletable() } } -/// A plugins manager that handles starting and stopping plugins. -/// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. -pub struct PluginsManager { - default_lib_prefix: String, - loader: Option, - plugins: Vec>, -} - -/// Unique identifier of plugin in plugin manager. Actually is just an index in the plugins list. -/// It's guaranteed that if intex is obtained from plugin manager, it's valid for this plugin manager. -/// (at least at this moment, when there is no pluing unload support). -/// Using it instead of plugin name allows to avoid checking for ``Option`` every time. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct PluginIndex(usize); - -/// Unique identifier of running plugin in plugin manager. -/// The ``RunningPligin`` insterface can be accessed through this index without -/// additional checks. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct RunningPluginIndex(PluginIndex); - -/// Trait allowing to use ``RunningPluginIndex`` as ``PluginIndex`` -pub trait PluginIndexTrait { - fn index(&self) -> PluginIndex; +pub trait RunningPluginRecord +{ + fn name(&self) -> &str; + fn path(&self) -> &str; + fn deletable(&self) -> bool; + fn stop(&mut self); + fn running(&self) -> &RunningPlugin; + fn running_mut(&mut self) -> &mut RunningPlugin; } -impl PluginIndexTrait for PluginIndex { - fn index(&self) -> PluginIndex { - *self +impl + RunningPluginRecord for PluginRecord +{ + fn name(&self) -> &str { + self.name() + } + fn path(&self) -> &str { + self.path() + } + fn deletable(&self) -> bool { + self.deletable() + } + fn stop(&mut self) { + self.running_plugin = None; + } + fn running(&self) -> &RunningPligin { + self.running_plugin.as_ref().unwrap() + } + fn running_mut(&mut self) -> &mut RunningPligin { + self.running_plugin.as_mut().unwrap() } } -impl PluginIndexTrait for RunningPluginIndex { - fn index(&self) -> PluginIndex { - self.0 - } +/// A plugins manager that handles starting and stopping plugins. +/// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. +pub struct PluginsManager { + default_lib_prefix: String, + loader: Option, + plugins: Vec>, } impl @@ -135,86 +137,81 @@ impl Self { let plugin_starter: StaticPlugin

= StaticPlugin::new(); - self.plugins.push(PluginInstance::new(plugin_starter)); + self.plugins.push(PluginRecord::new(plugin_starter)); self } - /// Returns `true` if the plugin with the given index exists in the manager. - pub fn check_plugin_index(&self, index: T) -> bool { - index.index().0 < self.plugins.len() - } - /// Returns plugin index by name - pub fn get_plugin_index(&self, name: &str) -> Option { - self.plugins - .iter() - .position(|p| p.name() == name) - .map(PluginIndex) + fn get_plugin_index(&self, name: &str) -> Option { + self.plugins.iter().position(|p| p.name() == name) } /// Returns plugin index by name or error if plugin not found - pub fn get_plugin_index_err(&self, name: &str) -> ZResult { + fn get_plugin_index_err(&self, name: &str) -> ZResult { self.get_plugin_index(name) .ok_or_else(|| format!("Plugin `{}` not found", name).into()) } - /// Returns running plugin index by name - pub fn get_running_plugin_index(&self, name: &str) -> Option { - self.get_plugin_index(name).and_then(|i| { - self.plugins[i.0] - .get_running_plugin() - .map(|_| RunningPluginIndex(i)) - }) + /// Lists the loaded plugins + pub fn plugins(&self) -> impl Iterator> + '_ { + self.plugins.iter() } - /// Returns running plugin index by name or error if plugin not found - pub fn get_running_plugin_index_err(&self, name: &str) -> ZResult { - self.get_running_plugin_index(name) - .ok_or_else(|| format!("Plugin `{}` not running", name).into()) + /// Lists the loaded plugins mutable + pub fn plugins_mut( + &mut self, + ) -> impl Iterator> + '_ { + self.plugins.iter_mut() } - /// Starts plugin. - /// Returns - /// Ok(true, index) => plugin was successfully started - /// Ok(false, index) => plugin was already running - /// Err(e) => starting the plugin failed due to `e` - pub fn start( - &mut self, - index: T, - args: &StartArgs, - ) -> ZResult<(bool, RunningPluginIndex)> { - let instance = &mut self.plugins[index.index().0]; - let already_started = instance.start(args)?; - Ok((already_started, RunningPluginIndex(index.index()))) + /// Lists the running plugins + pub fn running_plugins( + &self, + ) -> impl Iterator> + '_ { + self.plugins().filter_map(|p| p.running()) } - /// Stops `plugin`, returning `true` if it was indeed running. - pub fn stop(&mut self, index: RunningPluginIndex) -> ZResult { - let instance = &mut self.plugins[index.index().0]; - let was_running = instance.stop(); - Ok(was_running) + /// Lists the running plugins mutable + pub fn running_plugins_mut( + &mut self, + ) -> impl Iterator> + '_ { + self.plugins_mut().filter_map(|p| p.running_mut()) } - /// Lists the loaded plugins - pub fn plugins(&self) -> impl Iterator + '_ { - self.plugins.iter().enumerate().map(|(i, _)| PluginIndex(i)) + + /// Returns plugin record + pub fn plugin(&self, name: &str) -> ZResult<&PluginRecord> { + Ok(&self.plugins[self.get_plugin_index_err(name)?]) } - /// Lists the loaded plugins - pub fn running_plugins(&self) -> impl Iterator + '_ { - self.plugins.iter().enumerate().filter_map(|(i, p)| { - if p.get_running_plugin().is_some() { - Some(RunningPluginIndex(PluginIndex(i))) - } else { - None - } - }) + + /// Returns mutable plugin record + pub fn plugin_mut( + &mut self, + name: &str, + ) -> ZResult<&mut PluginRecord> { + let index = self.get_plugin_index_err(name)?; + Ok(&mut self.plugins[index]) } - /// Returns running plugin interface of plugin or none if plugin is stopped - pub fn running_plugin(&self, index: RunningPluginIndex) -> &RunningPlugin { - self.plugins[index.index().0].get_running_plugin().unwrap() + + /// Returns running plugin record + pub fn running_plugin( + &self, + name: &str, + ) -> ZResult<&dyn RunningPluginRecord> { + Ok(self + .plugin(name)? + .running() + .ok_or_else(|| format!("Plugin `{}` is not running", name))?) } - /// Returns plugin information - pub fn plugin(&self, index: T) -> &dyn PluginInfo { - self.plugins[index.index().0].as_plugin_info() + + /// Returns mutable running plugin record + pub fn running_plugin_mut( + &mut self, + name: &str, + ) -> ZResult<&mut dyn RunningPluginRecord> { + Ok(self + .plugin_mut(name)? + .running_mut() + .ok_or_else(|| format!("Plugin `{}` is not running", name))?) } fn load_plugin( @@ -231,7 +228,7 @@ impl ZResult { + ) -> ZResult<&mut PluginRecord> { let name = name.as_ref(); if self.get_plugin_index(name).is_some() { bail!("Plugin `{}` already loaded", name); @@ -245,15 +242,15 @@ impl p, Err(e) => bail!("After loading `{:?}`: {}", &p, e), }; - self.plugins.push(PluginInstance::new(plugin)); - Ok(PluginIndex(self.plugins.len() - 1)) + self.plugins.push(PluginRecord::new(plugin)); + Ok(self.plugins.last_mut().unwrap()) } /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( &mut self, name: T, paths: &[P], - ) -> ZResult { + ) -> ZResult<&mut PluginRecord> { let name = name.as_ref(); if self.get_plugin_index(name).is_some() { bail!("Plugin `{}` already loaded", name); @@ -263,8 +260,8 @@ impl { let plugin = Self::load_plugin(name, lib, p)?; - self.plugins.push(PluginInstance::new(plugin)); - return Ok(PluginIndex(self.plugins.len() - 1)); + self.plugins.push(PluginRecord::new(plugin)); + return Ok(self.plugins.last_mut().unwrap()); } Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 6f09c98d7c..4753edd56b 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -73,10 +73,8 @@ impl ConfigValidator for AdminSpace { new: &serde_json::Map, ) -> ZResult>> { let plugins_mgr = zlock!(self.context.plugins_mgr); - let index = plugins_mgr.get_running_plugin_index_err(name)?; - plugins_mgr - .running_plugin(index) - .config_checker(path, current, new) + let plugin = plugins_mgr.running_plugin(name)?; + plugin.running().config_checker(path, current, new) } } @@ -125,10 +123,7 @@ impl AdminSpace { let mut active_plugins = plugins_mgr .running_plugins() - .map(|index| { - let info = plugins_mgr.plugin(index); - (info.name().to_string(), info.path().to_string()) - }) + .map(|rec| (rec.name().to_string(), rec.path().to_string())) .collect::>(); let context = Arc::new(AdminContext { @@ -193,28 +188,32 @@ impl AdminSpace { match diff { PluginDiff::Delete(name) => { active_plugins.remove(name.as_str()); - if let Some(index) = plugins_mgr.get_running_plugin_index(&name) { - let _ = plugins_mgr.stop(index); + if let Ok(running) = plugins_mgr.running_plugin_mut(&name) { + running.stop() } } PluginDiff::Start(plugin) => { let name = &plugin.name; - let index = if let Some(paths) = &plugin.paths { + let rec = if let Some(paths) = &plugin.paths { plugins_mgr.load_plugin_by_paths(name, paths) } else { plugins_mgr.load_plugin_by_backend_name(name, &plugin.name) }; - match index { - Ok(index) => { - let path = plugins_mgr.plugin(index).path().to_string(); - log::info!("Loaded plugin `{}` from {}", name, path); - match plugins_mgr.start(index, &admin.context.runtime) { - Ok((true, _)) => { - active_plugins.insert(name.into(), path.clone()); + match rec { + Ok(rec) => { + log::info!( + "Loaded plugin `{}` from {}", + rec.name(), + rec.path() + ); + match rec.start(&admin.context.runtime) { + Ok((true, rec)) => { + active_plugins + .insert(name.into(), rec.path().to_string()); log::info!( "Successfully started plugin `{}` from {}", - name, - path + rec.name(), + rec.path() ); } Ok((false, _)) => { @@ -437,8 +436,7 @@ fn router_data(context: &AdminContext, query: Query) { let plugins_mgr = zlock!(context.plugins_mgr); plugins_mgr .running_plugins() - .map(|index| plugins_mgr.plugin(index)) - .map(|info| (info.name(), json!({ "path": info.path() }))) + .map(|rec| (rec.name(), json!({ "path": rec.path() }))) .collect() }; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index aadab85552..89540b4199 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -112,6 +112,17 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na } }; + // for index in plugins.plugins() { + // let info = plugins[index].info(); + // let required = required_plugins.contains(name); + // log::info!( + // "Starting {req} plugin \"{name}\"", + // req = if required { "required" } else { "" } + // ); + + // let index = plugins.start(index, &runtime); + // } + for (name, path, start_result) in plugins.start_all(&runtime) { let required = required_plugins.contains(name); log::info!( From 6a84494a147693aa0d4c667e56028d5a74cb738f Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 27 Oct 2023 15:13:13 +0200 Subject: [PATCH 026/106] compiles --- .../zenoh-plugin-storage-manager/src/lib.rs | 68 +++++++++---------- zenoh/src/net/runtime/adminspace.rs | 18 ++--- zenohd/src/main.rs | 61 ++++++++++------- 3 files changed, 77 insertions(+), 70 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 497ddd48ac..538680019a 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -31,9 +31,13 @@ use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::sync::*; use zenoh::runtime::Runtime; use zenoh::Session; +use zenoh_backend_traits::config::ConfigDiff; +use zenoh_backend_traits::config::PluginConfig; +use zenoh_backend_traits::config::StorageConfig; +use zenoh_backend_traits::config::VolumeConfig; use zenoh_backend_traits::VolumePlugin; use zenoh_core::zlock; -use zenoh_result::{bail, ZResult}; +use zenoh_result::ZResult; use zenoh_util::LibLoader; mod backends_mgt; @@ -104,14 +108,15 @@ impl StorageRuntimeInner { let session = Arc::new(zenoh::init(runtime.clone()).res_sync().unwrap()); - let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX).add_static::(); + let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX) + .add_static::(); let mut new_self = StorageRuntimeInner { name, runtime, session, storages: Default::default(), - plugins_manager + plugins_manager, }; new_self.spawn_volume(VolumeConfig { name: MEMORY_BACKEND_NAME.into(), @@ -131,7 +136,7 @@ impl StorageRuntimeInner { fn update>(&mut self, diffs: I) -> ZResult<()> { for diff in diffs { match diff { - ConfigDiff::DeleteVolume(volume) => self.kill_volume(&volume.name), + ConfigDiff::DeleteVolume(volume) => self.kill_volume(&volume.name)?, ConfigDiff::AddVolume(volume) => { self.spawn_volume(volume)?; } @@ -141,7 +146,7 @@ impl StorageRuntimeInner { } Ok(()) } - fn kill_volume>(&mut self, name: T) { + fn kill_volume>(&mut self, name: T) -> ZResult<()> { let name = name.as_ref(); if let Some(storages) = self.storages.remove(name) { async_std::task::block_on(futures::future::join_all( @@ -150,7 +155,8 @@ impl StorageRuntimeInner { .map(|s| async move { s.send(StorageMessage::Stop) }), )); } - self.plugins_manager.stop(name); + self.plugins_manager.running_plugin_mut(name)?.stop(); + Ok(()) } fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); @@ -162,7 +168,7 @@ impl StorageRuntimeInner { self.plugins_manager .load_plugin_by_backend_name(volume_id, backend_name)?; } - self.plugins_manager.start(volume_id, &config)?; + self.plugins_manager.plugin_mut(volume_id)?.start(&config)?; Ok(()) } fn kill_storage(&mut self, config: StorageConfig) { @@ -182,29 +188,23 @@ impl StorageRuntimeInner { fn spawn_storage(&mut self, storage: StorageConfig) -> ZResult<()> { let admin_key = self.status_key() + "/storages/" + &storage.name; let volume_id = storage.volume_id.clone(); - if let Some(backend) = self.plugins_manager.plugin(&volume_id) { - let storage_name = storage.name.clone(); - let in_interceptor = backend.incoming_data_interceptor(); - let out_interceptor = backend.outgoing_data_interceptor(); - let stopper = async_std::task::block_on(create_and_start_storage( - admin_key, - storage, - &backend, - in_interceptor, - out_interceptor, - self.session.clone(), - ))?; - self.storages - .entry(volume_id) - .or_default() - .insert(storage_name, stopper); - Ok(()) - } else { - bail!( - "`{}` volume doesn't support the required storage configuration", - volume_id - ) - } + let backend = self.plugins_manager.running_plugin(&volume_id)?; + let storage_name = storage.name.clone(); + let in_interceptor = backend.running().incoming_data_interceptor(); + let out_interceptor = backend.running().outgoing_data_interceptor(); + let stopper = async_std::task::block_on(create_and_start_storage( + admin_key, + storage, + backend.running(), + in_interceptor, + out_interceptor, + self.session.clone(), + ))?; + self.storages + .entry(volume_id) + .or_default() + .insert(storage_name, stopper); + Ok(()) } } impl From for StorageRuntime { @@ -251,8 +251,8 @@ impl RunningPluginTrait for StorageRuntime { }); let guard = self.0.lock().unwrap(); with_extended_string(&mut key, &["/volumes/"], |key| { - for (volume_id, (lib_path, volume)) in guard.plugins_manager.running_plugins() { - with_extended_string(key, &[volume_id], |key| { + for plugin in guard.plugins_manager.running_plugins() { + with_extended_string(key, &[plugin.name()], |key| { with_extended_string(key, &["/__path__"], |key| { if keyexpr::new(key.as_str()) .unwrap() @@ -260,7 +260,7 @@ impl RunningPluginTrait for StorageRuntime { { responses.push(zenoh::plugins::Response::new( key.clone(), - lib_path.into(), + plugin.path().into(), )) } }); @@ -270,7 +270,7 @@ impl RunningPluginTrait for StorageRuntime { { responses.push(zenoh::plugins::Response::new( key.clone(), - volume.get_admin_status(), + plugin.running().get_admin_status(), )) } }); diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 4753edd56b..4fff3c764e 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -640,19 +640,15 @@ fn plugins_status(context: &AdminContext, query: Query) { let guard = zlock!(context.plugins_mgr); let mut root_key = format!("@/router/{}/status/plugins/", &context.zid_str); - for index in guard.running_plugins() { - let info = guard.plugin(index); - let name = info.name(); - let path = info.path(); - let plugin = guard.running_plugin(index); - with_extended_string(&mut root_key, &[name], |plugin_key| { + for plugin in guard.running_plugins() { + with_extended_string(&mut root_key, &[plugin.name()], |plugin_key| { with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { if let Ok(key_expr) = KeyExpr::try_from(plugin_path_key.clone()) { if query.key_expr().intersects(&key_expr) { if let Err(e) = query .reply(Ok(Sample::new( key_expr, - Value::from(path).encoding(KnownEncoding::AppJson.into()), + Value::from(plugin.path()).encoding(KnownEncoding::AppJson.into()), ))) .res() { @@ -672,7 +668,7 @@ fn plugins_status(context: &AdminContext, query: Query) { return; } match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - plugin.adminspace_getter(&selector, plugin_key) + plugin.running().adminspace_getter(&selector, plugin_key) })) { Ok(Ok(responses)) => { for response in responses { @@ -691,15 +687,15 @@ fn plugins_status(context: &AdminContext, query: Query) { } } Ok(Err(e)) => { - log::error!("Plugin {} bailed from responding to {}: {}", name, query.key_expr(), e) + log::error!("Plugin {} bailed from responding to {}: {}", plugin.name(), query.key_expr(), e) } Err(e) => match e .downcast_ref::() .map(|s| s.as_str()) .or_else(|| e.downcast_ref::<&str>().copied()) { - Some(e) => log::error!("Plugin {} panicked while responding to {}: {}", name, query.key_expr(), e), - None => log::error!("Plugin {} panicked while responding to {}. The panic message couldn't be recovered.", name, query.key_expr()), + Some(e) => log::error!("Plugin {} panicked while responding to {}: {}", plugin.name(), query.key_expr(), e), + None => log::error!("Plugin {} panicked while responding to {}. The panic message couldn't be recovered.", plugin.name(), query.key_expr()), }, } }); diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 89540b4199..6a2bc0a682 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -76,7 +76,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na let config = config_from_args(&args); log::info!("Initial conf: {}", &config); - let mut plugins = PluginsManager::dynamic(config.libloader(), "zenoh_plugin_"); + let mut plugin_mgr = PluginsManager::dynamic(config.libloader(), "zenoh_plugin_"); // Static plugins are to be added here, with `.add_static::()` let mut required_plugins = HashSet::new(); for plugin_load in config.plugins().load_requests() { @@ -90,8 +90,8 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na req = if required { "required" } else { "" } ); if let Err(e) = match paths { - None => plugins.load_plugin_by_backend_name(&name, &name), - Some(paths) => plugins.load_plugin_by_paths(name.clone(), &paths), + None => plugin_mgr.load_plugin_by_backend_name(&name, &name), + Some(paths) => plugin_mgr.load_plugin_by_paths(name.clone(), &paths), } { if required { panic!("Plugin load failure: {}", e) @@ -112,42 +112,53 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na } }; - // for index in plugins.plugins() { - // let info = plugins[index].info(); - // let required = required_plugins.contains(name); - // log::info!( - // "Starting {req} plugin \"{name}\"", - // req = if required { "required" } else { "" } - // ); - - // let index = plugins.start(index, &runtime); - // } - - for (name, path, start_result) in plugins.start_all(&runtime) { - let required = required_plugins.contains(name); + for plugin in plugin_mgr.plugins_mut() { + let required = required_plugins.contains(plugin.name()); log::info!( "Starting {req} plugin \"{name}\"", - req = if required { "required" } else { "" } + req = if required { "required" } else { "" }, + name = plugin.name() ); - match start_result { - Ok(Some(_)) => log::info!("Successfully started plugin {} from {:?}", name, path), - Ok(None) => log::warn!("Plugin {} from {:?} wasn't loaded, as an other plugin by the same name is already running", name, path), + match plugin.start(&runtime) { + Ok(_) => { + log::info!( + "Successfully started plugin {} from {:?}", + plugin.name(), + plugin.path() + ); + } Err(e) => { let report = match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| e.to_string())) { Ok(s) => s, - Err(_) => panic!("Formatting the error from plugin {} ({:?}) failed, this is likely due to ABI unstability.\r\nMake sure your plugin was built with the same version of cargo as zenohd", name, path), + Err(_) => panic!("Formatting the error from plugin {} ({:?}) failed, this is likely due to ABI unstability.\r\nMake sure your plugin was built with the same version of cargo as zenohd", plugin.name(), plugin.path()), }; if required { - panic!("Plugin \"{name}\" failed to start: {}", if report.is_empty() {"no details provided"} else {report.as_str()}); - }else { - log::error!("Required plugin \"{name}\" failed to start: {}", if report.is_empty() {"no details provided"} else {report.as_str()}); + panic!( + "Plugin \"{}\" failed to start: {}", + plugin.name(), + if report.is_empty() { + "no details provided" + } else { + report.as_str() + } + ); + } else { + log::error!( + "Required plugin \"{}\" failed to start: {}", + plugin.name(), + if report.is_empty() { + "no details provided" + } else { + report.as_str() + } + ); } } } } log::info!("Finished loading plugins"); - AdminSpace::start(&runtime, plugins, LONG_VERSION.clone()).await; + AdminSpace::start(&runtime, plugin_mgr, LONG_VERSION.clone()).await; future::pending::<()>().await; }); From 21f03a81ed8e10c6c441c315902c7b3a9ab3f4a4 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 27 Oct 2023 17:36:04 +0200 Subject: [PATCH 027/106] static memory plugin fix --- .../src/memory_backend/mod.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index 17927c40cf..fb148da0e4 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -13,21 +13,17 @@ // use async_std::sync::RwLock; use async_trait::async_trait; -use zenoh_plugin_trait::Plugin; use std::collections::HashMap; use std::sync::Arc; use zenoh::prelude::r#async::*; use zenoh::time::Timestamp; use zenoh_backend_traits::config::{StorageConfig, VolumeConfig}; use zenoh_backend_traits::*; +use zenoh_plugin_trait::Plugin; use zenoh_result::ZResult; use crate::MEMORY_BACKEND_NAME; -pub fn create_memory_backend(config: VolumeConfig) -> ZResult { - Ok(Box::new(MemoryBackend { config })) -} - pub struct MemoryBackend { config: VolumeConfig, } @@ -38,8 +34,10 @@ impl Plugin for MemoryBackend { const STATIC_NAME: &'static str = MEMORY_BACKEND_NAME; - fn start(name: &str, args: &Self::StartArgs) -> ZResult { - todo!() + fn start(_: &str, args: &VolumeConfig) -> ZResult { + Ok(Box::new(MemoryBackend { + config: args.clone(), + })) } } From fafb5cd3ef128f36894c9c54d34181dfe5ff2a7d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 29 Oct 2023 00:50:43 +0200 Subject: [PATCH 028/106] compare version improved --- Cargo.lock | 1 + plugins/zenoh-backend-traits/src/config.rs | 8 +- plugins/zenoh-backend-traits/src/lib.rs | 10 +- plugins/zenoh-plugin-trait/Cargo.toml | 1 + plugins/zenoh-plugin-trait/src/lib.rs | 15 ++- plugins/zenoh-plugin-trait/src/loading.rs | 30 +++--- plugins/zenoh-plugin-trait/src/vtable.rs | 102 ++++++++++++++++++--- zenoh/src/net/runtime/adminspace.rs | 20 ++-- zenoh/src/net/runtime/mod.rs | 10 +- zenoh/src/plugins/sealed.rs | 8 +- 10 files changed, 154 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ff6e7cfd4..0fe53d1dc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4936,6 +4936,7 @@ dependencies = [ name = "zenoh-plugin-trait" version = "0.11.0-dev" dependencies = [ + "const_format", "libloading", "log", "serde_json", diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index 2672a2f346..d705adb0ed 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -68,12 +68,12 @@ pub struct ReplicaConfig { pub delta: Duration, } -const VOLUME_CONFIG_VERSION: &str = "1"; - impl CompatibilityVersion for VolumeConfig { - fn version() -> &'static str { + fn version() -> u64 { + 1 + } + fn features() -> &'static str { concat_enabled_features!( - VOLUME_CONFIG_VERSION, "auth_pubkey", "auth_usrpwd", "complete_n", diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 325e5a6981..cec49188e3 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -132,13 +132,13 @@ //! ``` use async_trait::async_trait; -use zenoh_plugin_trait::{CompatibilityVersion, concat_enabled_features}; use std::sync::Arc; use zenoh::prelude::{KeyExpr, OwnedKeyExpr, Sample, Selector}; use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; +use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; pub mod config; use config::{StorageConfig, VolumeConfig}; @@ -217,12 +217,12 @@ pub trait Volume: Send + Sync { pub type VolumePlugin = Box; -const VOLUME_PLUGIN_VERSION: &str = "1"; - impl CompatibilityVersion for VolumePlugin { - fn version() -> &'static str { + fn version() -> u64 { + 1 + } + fn features() -> &'static str { concat_enabled_features!( - VOLUME_PLUGIN_VERSION, "auth_pubkey", "auth_usrpwd", "complete_n", diff --git a/plugins/zenoh-plugin-trait/Cargo.toml b/plugins/zenoh-plugin-trait/Cargo.toml index 1df89f538a..2a45c7f6cf 100644 --- a/plugins/zenoh-plugin-trait/Cargo.toml +++ b/plugins/zenoh-plugin-trait/Cargo.toml @@ -37,3 +37,4 @@ serde_json = { workspace = true } zenoh-macros = { workspace = true } zenoh-result = { workspace = true } zenoh-util = { workspace = true } +const_format = { workspace = true } \ No newline at end of file diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 47b9d153bb..ec1625f49b 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -24,22 +24,29 @@ pub mod vtable; use zenoh_result::ZResult; pub mod prelude { - pub use crate::{loading::*, vtable::*, CompatibilityVersion, Plugin, concat_enabled_features}; + pub use crate::{concat_enabled_features, loading::*, vtable::*, CompatibilityVersion, Plugin}; } #[macro_export] macro_rules! concat_enabled_features { - ($version:ident, $($feature:literal),*) => { + ($($feature:literal),*) => { { use const_format::concatcp; - const_format::concatcp!($version $(, + const_format::concatcp!("" $(, if cfg!(feature = $feature) { concatcp!(" ", $feature) } else { "" } )*) } }; } + pub trait CompatibilityVersion { - fn version() -> &'static str; + /// The version of the structure implementing this trait. After any channge in the structure or it's dependencies + /// whcich may affect the ABI, this version should be incremented. + fn version() -> u64; + /// The features enabled when the structure implementing this trait was compiled. + /// Different features between the plugin and the host may cuase ABI incompatibility even if the structure version is the same. + /// Use `concat_enabled_features!` to generate this string. + fn features() -> &'static str; } pub trait Plugin: Sized + 'static { diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 45fe71d8d5..0e01e1acc5 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -224,14 +224,16 @@ impl, T1: AsRef>( &mut self, name: T, backend_name: T1, - ) -> ZResult<&mut PluginRecord> { + ) -> ZResult<(bool, &mut PluginRecord)> { let name = name.as_ref(); - if self.get_plugin_index(name).is_some() { - bail!("Plugin `{}` already loaded", name); + if let Some(index) = self.get_plugin_index(name) { + return Ok((false, &mut self.plugins[index])); } let backend_name = backend_name.as_ref(); let (lib, p) = match &mut self.loader { @@ -243,17 +245,19 @@ impl bail!("After loading `{:?}`: {}", &p, e), }; self.plugins.push(PluginRecord::new(plugin)); - Ok(self.plugins.last_mut().unwrap()) + Ok((true, self.plugins.last_mut().unwrap())) } /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) + /// Returns a tuple of (retval, plugin_record) + /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( &mut self, name: T, paths: &[P], - ) -> ZResult<&mut PluginRecord> { + ) -> ZResult<(bool, &mut PluginRecord)> { let name = name.as_ref(); - if self.get_plugin_index(name).is_some() { - bail!("Plugin `{}` already loaded", name); + if let Some(index) = self.get_plugin_index(name) { + return Ok((false, &mut self.plugins[index])); } for path in paths { let path = path.as_ref(); @@ -261,7 +265,7 @@ impl { let plugin = Self::load_plugin(name, lib, p)?; self.plugins.push(PluginRecord::new(plugin)); - return Ok(self.plugins.last_mut().unwrap()); + return Ok((true, self.plugins.last_mut().unwrap())); } Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), } @@ -356,9 +360,11 @@ impl DynamicPlugin { fn new(name: String, lib: Library, path: PathBuf) -> ZResult { + log::debug!("Loading plugin {}", &path.to_str().unwrap(),); let get_plugin_loader_version = unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; let plugin_loader_version = get_plugin_loader_version(); + log::debug!("Plugin loader version: {}", &plugin_loader_version); if plugin_loader_version != PLUGIN_LOADER_VERSION { bail!( "Plugin loader version mismatch: host = {}, plugin = {}", @@ -369,15 +375,17 @@ impl let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; let plugin_compatibility_record = get_compatibility(); let host_compatibility_record = Compatibility::new::(); + log::debug!( + "Plugin compativilty record: {:?}", + &plugin_compatibility_record + ); if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { bail!( - "Plugin compatibility mismatch:\nhost = {:?}\nplugin = {:?}\n", + "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", host_compatibility_record, plugin_compatibility_record ); } - - // TODO: check loader version and compatibility let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 59caf399b7..8c03283b2a 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + // // Copyright (c) 2023 ZettaScale Technology // @@ -25,8 +27,56 @@ pub struct PluginVTable { pub start: StartFn, } impl CompatibilityVersion for PluginVTable { - fn version() -> &'static str{ - "1" + fn version() -> u64 { + 1 + } + fn features() -> &'static str { + concat_enabled_features!( + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ) + } +} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct StructVersion { + pub version: u64, + pub name: &'static str, + pub features: &'static str, +} + +impl StructVersion { + pub fn new() -> Self { + Self { + version: T::version(), + name: std::any::type_name::(), + features: T::features(), + } + } +} + +impl Display for StructVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + " version: {}\n type: {}\n features: {}\n", + self.version, self.name, self.features + ) } } @@ -34,21 +84,22 @@ impl CompatibilityVersion for PluginVTable() -> Self { + let rust_version = RustVersion::new(); + let vtable_version = StructVersion::new::>(); + let start_args_version = StructVersion::new::(); + let running_plugin_version = StructVersion::new::(); Self { - rust_version: RustVersion::new(), - vtable_version: PluginVTable::::version(), - start_args_version: (std::any::type_name::(), StartArgs::version()), - running_plugin_version: ( - std::any::type_name::(), - RunningPlugin::version(), - ), + rust_version, + vtable_version, + start_args_version, + running_plugin_version, } } pub fn are_compatible(&self, other: &Self) -> bool { @@ -59,6 +110,19 @@ impl Compatibility { } } +impl Display for Compatibility { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}\nVTable:{}StartArgs:{}RunningPlugin:{}", + self.rust_version, + self.vtable_version, + self.start_args_version, + self.running_plugin_version + ) + } +} + #[repr(C)] #[derive(Debug, PartialEq, Eq, Clone)] pub struct RustVersion { @@ -69,6 +133,20 @@ pub struct RustVersion { commit: &'static str, } +impl Display for RustVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Rust {}.{}.{}{} commit {}", + self.major, + self.minor, + self.patch, + if self.stable { "" } else { "-nightly" }, + self.commit + ) + } +} + const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); impl RustVersion { pub fn new() -> Self { diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 4fff3c764e..de6cef745f 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -200,12 +200,20 @@ impl AdminSpace { plugins_mgr.load_plugin_by_backend_name(name, &plugin.name) }; match rec { - Ok(rec) => { - log::info!( - "Loaded plugin `{}` from {}", - rec.name(), - rec.path() - ); + Ok((loaded, rec)) => { + if loaded { + log::info!( + "Loaded plugin `{}` from {}", + rec.name(), + rec.path() + ); + } else { + log::warn!( + "Plugin `{}` was already loaded from {}", + rec.name(), + rec.path() + ); + } match rec.start(&admin.context.runtime) { Ok((true, rec)) => { active_plugins diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index f3ca4a78db..c320f538d2 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -38,7 +38,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::{CompatibilityVersion, concat_enabled_features}; +use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; @@ -66,12 +66,12 @@ pub struct Runtime { state: Arc, } -const RUNTIME_VERSION: &str = "1"; - impl CompatibilityVersion for Runtime { - fn version() -> &'static str { + fn version() -> u64 { + 1 + } + fn features() -> &'static str { concat_enabled_features!( - RUNTIME_VERSION, "auth_pubkey", "auth_usrpwd", "complete_n", diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 5b2d48374b..b68dd30253 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -31,12 +31,12 @@ pub type StartArgs = Runtime; /// A zenoh plugin, when started, must return this type. pub type RunningPlugin = Box; -const RUNNING_PLUGIN_VERSION: &str = "1"; - impl CompatibilityVersion for RunningPlugin { - fn version() -> &'static str { + fn version() -> u64 { + 1 + } + fn features() -> &'static str { concat_enabled_features!( - RUNNING_PLUGIN_VERSION, "auth_pubkey", "auth_usrpwd", "complete_n", From f080df61dd6fd68f0698e084d344ea762b929271 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 29 Oct 2023 22:53:49 +0100 Subject: [PATCH 029/106] moved feature list to crate level --- Cargo.lock | 1 + plugins/zenoh-backend-traits/Cargo.toml | 5 ++++- plugins/zenoh-backend-traits/src/config.rs | 22 +++---------------- plugins/zenoh-backend-traits/src/lib.rs | 25 ++++++---------------- plugins/zenoh-plugin-trait/src/lib.rs | 10 ++++----- plugins/zenoh-plugin-trait/src/vtable.rs | 21 +++--------------- zenoh/build.rs | 1 + zenoh/src/lib.rs | 23 ++++++++++++++++++++ zenoh/src/net/runtime/mod.rs | 22 ++----------------- zenoh/src/plugins/sealed.rs | 20 +---------------- zenohd/Cargo.toml | 1 + 11 files changed, 51 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fe53d1dc3..af56b38b7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5083,6 +5083,7 @@ dependencies = [ "rand 0.8.5", "rustc_version 0.4.0", "zenoh", + "zenoh_backend_traits", ] [[package]] diff --git a/plugins/zenoh-backend-traits/Cargo.toml b/plugins/zenoh-backend-traits/Cargo.toml index 8c13247c5e..f2b8a4a1eb 100644 --- a/plugins/zenoh-backend-traits/Cargo.toml +++ b/plugins/zenoh-backend-traits/Cargo.toml @@ -36,4 +36,7 @@ zenoh-result = { workspace = true } zenoh-util = { workspace = true } schemars = { workspace = true } zenoh-plugin-trait = { workspace = true } -const_format = { workspace = true } \ No newline at end of file +const_format = { workspace = true } + +[features] +default = [] diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index d705adb0ed..8587993a7c 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -1,3 +1,4 @@ +use const_format::concatcp; // // Copyright (c) 2023 ZettaScale Technology // @@ -17,7 +18,7 @@ use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; -use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; +use zenoh_plugin_trait::CompatibilityVersion; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] @@ -73,24 +74,7 @@ impl CompatibilityVersion for VolumeConfig { 1 } fn features() -> &'static str { - concat_enabled_features!( - "auth_pubkey", - "auth_usrpwd", - "complete_n", - "shared-memory", - "stats", - "transport_multilink", - "transport_quic", - "transport_serial", - "transport_unixpipe", - "transport_tcp", - "transport_tls", - "transport_udp", - "transport_unixsock-stream", - "transport_ws", - "unstable", - "default" - ) + concatcp!(zenoh::FEATURES, crate::FEATURES) } } diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index cec49188e3..bd4730119f 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -132,6 +132,7 @@ //! ``` use async_trait::async_trait; +use const_format::concatcp; use std::sync::Arc; use zenoh::prelude::{KeyExpr, OwnedKeyExpr, Sample, Selector}; use zenoh::queryable::ReplyBuilder; @@ -143,6 +144,11 @@ use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; pub mod config; use config::{StorageConfig, VolumeConfig}; +// No features are actually used in this crate, but this dummy list allows to demonstrate how to combine feature lists +// from multiple crates. See implementation of `CompatibilityVersion::features()` for more `VolumePlugin` and `VolumeConfig` types +const FEATURES: &str = + concat_enabled_features!(prefix = "zenoh-backend-traits", features = ["default"]); + /// Capability of a storage indicates the guarantees of the storage /// It is used by the storage manager to take decisions on the trade-offs to ensure correct performance pub struct Capability { @@ -222,24 +228,7 @@ impl CompatibilityVersion for VolumePlugin { 1 } fn features() -> &'static str { - concat_enabled_features!( - "auth_pubkey", - "auth_usrpwd", - "complete_n", - "shared-memory", - "stats", - "transport_multilink", - "transport_quic", - "transport_serial", - "transport_unixpipe", - "transport_tcp", - "transport_tls", - "transport_udp", - "transport_unixsock-stream", - "transport_ws", - "unstable", - "default" - ) + concatcp!(zenoh::FEATURES, crate::FEATURES) } } diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index ec1625f49b..eb71a5f36c 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -29,11 +29,11 @@ pub mod prelude { #[macro_export] macro_rules! concat_enabled_features { - ($($feature:literal),*) => { + (prefix = $prefix:literal, features = [$($feature:literal),*]) => { { use const_format::concatcp; - const_format::concatcp!("" $(, - if cfg!(feature = $feature) { concatcp!(" ", $feature) } else { "" } + concatcp!("" $(, + if cfg!(feature = $feature) { concatcp!(" ", concatcp!($prefix, "/", $feature)) } else { "" } )*) } }; @@ -43,9 +43,9 @@ pub trait CompatibilityVersion { /// The version of the structure implementing this trait. After any channge in the structure or it's dependencies /// whcich may affect the ABI, this version should be incremented. fn version() -> u64; - /// The features enabled when the structure implementing this trait was compiled. + /// The features enabled during comiplation of the structure implementing this trait. /// Different features between the plugin and the host may cuase ABI incompatibility even if the structure version is the same. - /// Use `concat_enabled_features!` to generate this string. + /// Use `concat_enabled_features!` to generate this string fn features() -> &'static str; } diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 8c03283b2a..e1da1a579f 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -19,6 +19,8 @@ use zenoh_result::ZResult; pub type PluginLoaderVersion = u64; pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; +pub const FEATURES: &str = + concat_enabled_features!(prefix = "zenoh-plugin-trait", features = ["default"]); type StartFn = fn(&str, &StartArgs) -> ZResult; @@ -31,24 +33,7 @@ impl CompatibilityVersion for PluginVTable &'static str { - concat_enabled_features!( - "auth_pubkey", - "auth_usrpwd", - "complete_n", - "shared-memory", - "stats", - "transport_multilink", - "transport_quic", - "transport_serial", - "transport_unixpipe", - "transport_tcp", - "transport_tls", - "transport_udp", - "transport_unixsock-stream", - "transport_ws", - "unstable", - "default" - ) + FEATURES } } diff --git a/zenoh/build.rs b/zenoh/build.rs index 85d3c2d187..5be8828dfc 100644 --- a/zenoh/build.rs +++ b/zenoh/build.rs @@ -10,6 +10,7 @@ // Contributors: // ZettaScale Zenoh Team, // + fn main() { // Add rustc version to zenohd let version_meta = rustc_version::version_meta().unwrap(); diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index dbcc3b5827..37e01f8680 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -88,6 +88,7 @@ use scouting::ScoutBuilder; use std::future::Ready; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_macros::{kedefine, keformat, kewrite}; +use zenoh_plugin_trait::concat_enabled_features; use zenoh_protocol::core::WhatAmIMatcher; use zenoh_result::{zerror, ZResult}; @@ -98,6 +99,28 @@ pub use zenoh_result::ZResult as Result; const GIT_VERSION: &str = git_version!(prefix = "v", cargo_prefix = "v"); +pub const FEATURES: &str = concat_enabled_features!( + prefix = "zenoh", + features = [ + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ] +); + mod admin; #[macro_use] mod session; diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index c320f538d2..ef9db31862 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -28,7 +28,6 @@ use crate::config::{unwrap_or_default, Config, ModeDependent, Notifier}; use crate::GIT_VERSION; pub use adminspace::AdminSpace; use async_std::task::JoinHandle; -use const_format::concatcp; use futures::stream::StreamExt; use futures::Future; use std::any::Any; @@ -38,7 +37,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; +use zenoh_plugin_trait::CompatibilityVersion; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; @@ -71,24 +70,7 @@ impl CompatibilityVersion for Runtime { 1 } fn features() -> &'static str { - concat_enabled_features!( - "auth_pubkey", - "auth_usrpwd", - "complete_n", - "shared-memory", - "stats", - "transport_multilink", - "transport_quic", - "transport_serial", - "transport_unixpipe", - "transport_tcp", - "transport_tls", - "transport_udp", - "transport_unixsock-stream", - "transport_ws", - "unstable", - "default" - ) + crate::FEATURES } } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index b68dd30253..02768cd9b7 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -36,24 +36,7 @@ impl CompatibilityVersion for RunningPlugin { 1 } fn features() -> &'static str { - concat_enabled_features!( - "auth_pubkey", - "auth_usrpwd", - "complete_n", - "shared-memory", - "stats", - "transport_multilink", - "transport_quic", - "transport_serial", - "transport_unixpipe", - "transport_tcp", - "transport_tls", - "transport_udp", - "transport_unixsock-stream", - "transport_ws", - "unstable", - "default" - ) + crate::FEATURES } } @@ -101,6 +84,5 @@ pub trait RunningPluginTrait: Send + Sync { /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; -use zenoh_plugin_trait::concat_enabled_features; pub use zenoh_plugin_trait::CompatibilityVersion; pub use zenoh_plugin_trait::Plugin; diff --git a/zenohd/Cargo.toml b/zenohd/Cargo.toml index e589d1a888..c1c6f432e7 100644 --- a/zenohd/Cargo.toml +++ b/zenohd/Cargo.toml @@ -38,6 +38,7 @@ json5 = { workspace = true } lazy_static = { workspace = true } log = { workspace = true } zenoh = { workspace = true, features = ["unstable"] } +zenoh_backend_traits = { workspace = true } [dev-dependencies] rand = { workspace = true, features = ["default"] } From 0eaa517e9f0ef464d7391d25029de0d246b1c8e3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 30 Oct 2023 16:26:16 +0100 Subject: [PATCH 030/106] linter fix --- plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs index 5fb37409fe..9f29803fe3 100644 --- a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs +++ b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use zenoh::prelude::r#async::*; use zenoh::Session; use zenoh_backend_traits::config::StorageConfig; -use zenoh_backend_traits::Capability; +use zenoh_backend_traits::{Capability, VolumePlugin}; use zenoh_result::ZResult; pub struct StoreIntercept { @@ -30,7 +30,7 @@ pub struct StoreIntercept { pub(crate) async fn create_and_start_storage( admin_key: String, config: StorageConfig, - backend: &Box, + backend: &VolumePlugin, in_interceptor: Option Sample + Send + Sync>>, out_interceptor: Option Sample + Send + Sync>>, zenoh: Arc, From be3382d68dece7b308d81e41bfade60a3ee2453d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 31 Oct 2023 17:23:08 +0100 Subject: [PATCH 031/106] unfinished --- plugins/zenoh-plugin-trait/src/lib.rs | 22 +++++++ plugins/zenoh-plugin-trait/src/loading.rs | 74 +++++++++++++++++++---- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index eb71a5f36c..fef3315c8f 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -49,6 +49,28 @@ pub trait CompatibilityVersion { fn features() -> &'static str; } +pub enum PluginState { + Declared, + Loaded, + Started, +} + +pub enum PluginCondition { + Ok, + Warning(String), + Error(String), +} + +pub struct PluginStatus { + pub state: PluginState, + pub condition: PluginCondition, +} + +pub trait PluginControl { + fn plugins(&self) -> Vec<&str>; + fn status(&self, name: &str) -> PluginStatus; +} + pub trait Plugin: Sized + 'static { type StartArgs: CompatibilityVersion; type RunningPlugin: CompatibilityVersion; diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 0e01e1acc5..d4799f5e95 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -349,17 +349,28 @@ impl } } +struct + pub struct DynamicPlugin { - _lib: Library, - vtable: PluginVTable, - pub name: String, - pub path: PathBuf, + name: String, + lib: Option, + vtable: Option>, + path: Option, } impl DynamicPlugin { - fn new(name: String, lib: Library, path: PathBuf) -> ZResult { + pub fn new(name: String, lib: Library, path: PathBuf) -> Self { + Self { + name, + lib: None, + vtable: None, + path: None, + } + } + + fn get_vtable(path: &PathBuf) -> ZResult> { log::debug!("Loading plugin {}", &path.to_str().unwrap(),); let get_plugin_loader_version = unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; @@ -389,11 +400,52 @@ impl let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); - Ok(Self { - _lib: lib, - vtable, - name, - path, - }) + Ok(vtable) + } + + /// Tries to load a plugin with the name `libname` + `.so | .dll | .dylib` + /// in lib_loader's search paths. + /// Returns a tuple of (retval, plugin_record) + /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded + fn load_by_libname( + &self, + libloader: &LibLoader, + libname: &str, + ) -> ZResult { + let (lib, p) = unsafe { libloader.search_and_load(libname)? }; + + let plugin = match Self::load_plugin(name, lib, p.clone()) { + Ok(p) => p, + Err(e) => bail!("After loading `{:?}`: {}", &p, e), + }; + self.plugins.push(PluginRecord::new(plugin)); + Ok((true, self.plugins.last_mut().unwrap())) } + /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) + /// Returns a tuple of (retval, plugin_record) + /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded + pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( + &mut self, + name: T, + paths: &[P], + ) -> ZResult<(bool, &mut PluginRecord)> { + let name = name.as_ref(); + if let Some(index) = self.get_plugin_index(name) { + return Ok((false, &mut self.plugins[index])); + } + for path in paths { + let path = path.as_ref(); + match unsafe { LibLoader::load_file(path) } { + Ok((lib, p)) => { + let plugin = Self::load_plugin(name, lib, p)?; + self.plugins.push(PluginRecord::new(plugin)); + return Ok((true, self.plugins.last_mut().unwrap())); + } + Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), + } + } + bail!("Plugin '{}' not found in {:?}", name, &paths) + } +} + } From 13381ddd4ba306b98abe78df620978a622b82937 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 2 Nov 2023 17:36:38 +0100 Subject: [PATCH 032/106] unfinished --- .../zenoh-plugin-storage-manager/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/src/lib.rs | 17 - plugins/zenoh-plugin-trait/src/loading.rs | 436 +++++++++++------- zenoh/src/net/runtime/adminspace.rs | 2 +- zenohd/src/main.rs | 2 +- 5 files changed, 277 insertions(+), 182 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 538680019a..466253a4d6 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -168,7 +168,7 @@ impl StorageRuntimeInner { self.plugins_manager .load_plugin_by_backend_name(volume_id, backend_name)?; } - self.plugins_manager.plugin_mut(volume_id)?.start(&config)?; + self.plugins_manager.plugin_mut(volume_id)?.run(&config)?; Ok(()) } fn kill_storage(&mut self, config: StorageConfig) { diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index fef3315c8f..566e8d1127 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -49,23 +49,6 @@ pub trait CompatibilityVersion { fn features() -> &'static str; } -pub enum PluginState { - Declared, - Loaded, - Started, -} - -pub enum PluginCondition { - Ok, - Warning(String), - Error(String), -} - -pub struct PluginStatus { - pub state: PluginState, - pub condition: PluginCondition, -} - pub trait PluginControl { fn plugins(&self) -> Vec<&str>; fn status(&self, name: &str) -> PluginStatus; diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index d4799f5e95..2f068817cb 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -13,67 +13,178 @@ // use crate::*; use libloading::Library; +use serde_json::de; use std::path::PathBuf; use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; use zenoh_result::{bail, ZResult}; use zenoh_util::LibLoader; -pub struct PluginRecord { - starter: Box + Send + Sync>, +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum PluginState { + Declared, + Loaded, + Runnning, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum PluginCondition { + Ok, + Warning(String), + Error(String), +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct PluginStatus { + pub state: PluginState, + pub condition: PluginCondition, +} + +trait PluginLoader { + fn load( + &self, + ) -> ZResult + Send + Sync>>; +} + +trait PluginStarter { + fn start(&self, name: &str, args: &StartArgs) -> ZResult; +} + + +struct PluginRecord { + name: String, + path: Option, + condition: PluginCondition, + loader: Box + Send + Sync>, + starter: Option + Send + Sync>>, running_plugin: Option, } impl PluginRecord { - fn new + Send + Sync + 'static>(starter: T) -> Self { + fn new + Send + Sync + 'static>(name: String, loader: S) -> Self { Self { - starter: Box::new(starter), + name, + path: None, + condition: PluginCondition::Ok, + loader, + starter: None, running_plugin: None, } } - pub fn running(&self) -> Option<&dyn RunningPluginRecord> { - if self.running_plugin.is_some() { +} + +pub trait PluginInfo { + fn name(&self) -> &str; + fn path(&self) -> &str; + fn status(&self) -> PluginStatus; +} + +impl PluginInfo for PluginRecord { + fn name(&self) -> &str { + self.name.as_str() + } + fn path(&self) -> &str { + self.path.map_or("", |v| v.path()) + } + fn status(&self) -> PluginStatus { + PluginStatus { + state: if self.starter.is_some() { + if self.running_plugin.is_some() { + PluginState::Running + } else { + PluginState::Loaded + } + } else { + PluginState::Declared + }, + condition: self.condition, + } + } +} + +pub trait DeclaredPluginRecord : PluginInfo { + fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)>; + fn loaded(&self) -> Option<&dyn LoadedPluginRecord>; + fn loaded_mut( + &mut self + ) -> Option<&mut dyn LoadedPluginRecord>; +} + +impl DeclaredPluginRecord for PluginRecord { + fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)> { + if self.starter.is_some() { + Ok((false, self)) + } else { + match self.loader.load() { + Ok(starter) => { + self.starter = Some(starter); + self.condition = PluginCondition::Ok; + Ok((true, self)) + } + Err(e) => { + self.condition = PluginCondition::Error(format!("{}", e)); + Err(e) + } + } + } + } + fn loaded(&self) -> Option<&dyn LoadedPluginRecord> { + if self.starter.is_some() { Some(self) } else { None } } - pub fn running_mut( - &mut self, - ) -> Option<&mut dyn RunningPluginRecord> { - if self.running_plugin.is_some() { + fn loaded_mut( + &mut self + ) -> Option<&mut dyn LoadedPluginRecord> { + if self.starter.is_some() { Some(self) } else { None } } - pub fn start( - &mut self, - args: &StartArgs, - ) -> ZResult<(bool, &mut dyn RunningPluginRecord)> { +} + +pub trait LoadedPluginRecord : PluginInfo +{ + fn run(&mut self, args: &StartArgs) -> ZResult; + fn running(&self) -> Option<&dyn RunningPluginRecord>; + pub fn running_mut( + &mut self + ) -> Option<&mut dyn RunningPluginRecord>; +} + +impl LoadedPluginRecord for PluginRecord { + fn run(&mut self, args: &StartArgs) -> ZResult { + let starter = self.starter.as_ref().ok_or_else(|| format!("Plugin `{}` not loaded", self.name))?; let already_running = self.running_plugin.is_some(); if !already_running { - self.running_plugin = Some(self.starter.start(args)?); + self.running_plugin = Some(starter.start(self.name(), args)?); } - Ok((already_running, self)) - } - pub fn name(&self) -> &str { - self.starter.name() + Ok(self.running_plugin.as_ref().unwrap().clone()) } - pub fn path(&self) -> &str { - self.starter.path() + fn running(&self) -> Option<&dyn RunningPluginRecord> { + if self.running_plugin.is_some() { + Some(self) + } else { + None + } } - pub fn deletable(&self) -> bool { - self.starter.deletable() + fn running_mut( + &mut self + ) -> Option<&mut dyn RunningPluginRecord> { + if self.running_plugin.is_some() { + Some(self) + } else { + None + } } } pub trait RunningPluginRecord { - fn name(&self) -> &str; - fn path(&self) -> &str; - fn deletable(&self) -> bool; fn stop(&mut self); fn running(&self) -> &RunningPlugin; fn running_mut(&mut self) -> &mut RunningPlugin; @@ -82,15 +193,6 @@ pub trait RunningPluginRecord RunningPluginRecord for PluginRecord { - fn name(&self) -> &str { - self.name() - } - fn path(&self) -> &str { - self.path() - } - fn deletable(&self) -> bool { - self.deletable() - } fn stop(&mut self) { self.running_plugin = None; } @@ -136,8 +238,9 @@ impl( mut self, ) -> Self { - let plugin_starter: StaticPlugin

= StaticPlugin::new(); - self.plugins.push(PluginRecord::new(plugin_starter)); + let plugin_loader: StaticPlugin

= StaticPlugin::new(); + let name = P::STATIC_NAME.into(); + self.plugins.push(PluginRecord::new(name, Box::new(plugin_loader))); self } @@ -152,34 +255,48 @@ impl impl Iterator> + '_ { + /// Lists all plugins + pub fn plugins(&self) -> impl Iterator> + '_ { self.plugins.iter() } - /// Lists the loaded plugins mutable + /// Lists all plugins mutable pub fn plugins_mut( &mut self, ) -> impl Iterator> + '_ { self.plugins.iter_mut() } + /// Lists the loaded plugins + pub fn loaded_plugins( + &self, + ) -> impl Iterator> + '_ { + self.plugins().filter_map(|p| p.loaded()) + } + + /// Lists the loaded plugins mutable + pub fn loaded_plugins_mut( + &mut self, + ) -> impl Iterator> + '_ { + self.plugins_mut().filter_map(|p| p.loaded_mut()) + } + /// Lists the running plugins pub fn running_plugins( &self, ) -> impl Iterator> + '_ { - self.plugins().filter_map(|p| p.running()) + self.loaded_plugins().filter_map(|p| p.running()) } /// Lists the running plugins mutable pub fn running_plugins_mut( &mut self, ) -> impl Iterator> + '_ { - self.plugins_mut().filter_map(|p| p.running_mut()) + self.loaded_plugins_mut().filter_map(|p| p.running_mut()) } - /// Returns plugin record - pub fn plugin(&self, name: &str) -> ZResult<&PluginRecord> { + /// Returns single plugin record + pub fn plugin(&self, name: &str) -> ZResult<&dyn DeclaredPluginRecord> { Ok(&self.plugins[self.get_plugin_index_err(name)?]) } @@ -187,18 +304,40 @@ impl ZResult<&mut PluginRecord> { + ) -> ZResult<&mut DeclaredPluginRecord> { let index = self.get_plugin_index_err(name)?; Ok(&mut self.plugins[index]) } + /// Returns loaded plugin record + pub fn loaded_plugin( + &self, + name: &str, + ) -> ZResult<&dyn LoadedPluginRecord> { + Ok(self + .plugin(name)? + .loaded() + .ok_or_else(|| format!("Plugin `{}` not loaded", name))?) + } + + /// Returns mutable loaded plugin record + pub fn loaded_plugin_mut( + &mut self, + name: &str, + ) -> ZResult<&mut dyn LoadedPluginRecord> { + Ok(self + .plugin_mut(name)? + .loaded_mut() + .ok_or_else(|| format!("Plugin `{}` not loaded", name))?) + } + /// Returns running plugin record pub fn running_plugin( &self, name: &str, ) -> ZResult<&dyn RunningPluginRecord> { Ok(self - .plugin(name)? + .loaded_plugin(name)? .running() .ok_or_else(|| format!("Plugin `{}` is not running", name))?) } @@ -209,80 +348,69 @@ impl ZResult<&mut dyn RunningPluginRecord> { Ok(self - .plugin_mut(name)? + .loaded_plugin_mut(name)? .running_mut() .ok_or_else(|| format!("Plugin `{}` is not running", name))?) } - fn load_plugin( - name: &str, - lib: Library, - path: PathBuf, - ) -> ZResult> { - DynamicPlugin::new(name.into(), lib, path) - } - - /// Tries to load a plugin with the name `defaukt_lib_prefix` + `backend_name` + `.so | .dll | .dylib` - /// in lib_loader's search paths. - /// Returns a tuple of (retval, plugin_record) - /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded - pub fn load_plugin_by_backend_name, T1: AsRef>( - &mut self, - name: T, - backend_name: T1, - ) -> ZResult<(bool, &mut PluginRecord)> { - let name = name.as_ref(); - if let Some(index) = self.get_plugin_index(name) { - return Ok((false, &mut self.plugins[index])); - } - let backend_name = backend_name.as_ref(); - let (lib, p) = match &mut self.loader { - Some(l) => unsafe { l.search_and_load(&format!("{}{}", &self.default_lib_prefix, &backend_name))? }, - None => bail!("Can't load dynamic plugin `{}`, as dynamic loading is not enabled for this plugin manager.", &name), - }; - let plugin = match Self::load_plugin(name, lib, p.clone()) { - Ok(p) => p, - Err(e) => bail!("After loading `{:?}`: {}", &p, e), - }; - self.plugins.push(PluginRecord::new(plugin)); - Ok((true, self.plugins.last_mut().unwrap())) - } - /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) - /// Returns a tuple of (retval, plugin_record) - /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded - pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( - &mut self, - name: T, - paths: &[P], - ) -> ZResult<(bool, &mut PluginRecord)> { - let name = name.as_ref(); - if let Some(index) = self.get_plugin_index(name) { - return Ok((false, &mut self.plugins[index])); - } - for path in paths { - let path = path.as_ref(); - match unsafe { LibLoader::load_file(path) } { - Ok((lib, p)) => { - let plugin = Self::load_plugin(name, lib, p)?; - self.plugins.push(PluginRecord::new(plugin)); - return Ok((true, self.plugins.last_mut().unwrap())); - } - Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), - } - } - bail!("Plugin '{}' not found in {:?}", name, &paths) - } -} - -pub trait PluginInfo { - fn name(&self) -> &str; - fn path(&self) -> &str; - fn deletable(&self) -> bool; -} - -trait PluginStarter: PluginInfo { - fn start(&self, args: &StartArgs) -> ZResult; - fn as_plugin_info(&self) -> &dyn PluginInfo; + // fn load_plugin( + // name: &str, + // lib: Library, + // path: PathBuf, + // ) -> ZResult> { + // DynamicPlugin::new(name.into(), lib, path) + // } + + // /// Tries to load a plugin with the name `defaukt_lib_prefix` + `backend_name` + `.so | .dll | .dylib` + // /// in lib_loader's search paths. + // /// Returns a tuple of (retval, plugin_record) + // /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded + // pub fn load_plugin_by_backend_name, T1: AsRef>( + // &mut self, + // name: T, + // backend_name: T1, + // ) -> ZResult<(bool, &mut PluginRecord)> { + // let name = name.as_ref(); + // if let Some(index) = self.get_plugin_index(name) { + // return Ok((false, &mut self.plugins[index])); + // } + // let backend_name = backend_name.as_ref(); + // let (lib, p) = match &mut self.loader { + // Some(l) => unsafe { l.search_and_load(&format!("{}{}", &self.default_lib_prefix, &backend_name))? }, + // None => bail!("Can't load dynamic plugin `{}`, as dynamic loading is not enabled for this plugin manager.", &name), + // }; + // let plugin = match Self::load_plugin(name, lib, p.clone()) { + // Ok(p) => p, + // Err(e) => bail!("After loading `{:?}`: {}", &p, e), + // }; + // self.plugins.push(PluginRecord::new(plugin)); + // Ok((true, self.plugins.last_mut().unwrap())) + // } + // /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) + // /// Returns a tuple of (retval, plugin_record) + // /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded + // pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( + // &mut self, + // name: T, + // paths: &[P], + // ) -> ZResult<(bool, &mut PluginRecord)> { + // let name = name.as_ref(); + // if let Some(index) = self.get_plugin_index(name) { + // return Ok((false, &mut self.plugins[index])); + // } + // for path in paths { + // let path = path.as_ref(); + // match unsafe { LibLoader::load_file(path) } { + // Ok((lib, p)) => { + // let plugin = Self::load_plugin(name, lib, p)?; + // self.plugins.push(PluginRecord::new(plugin)); + // return Ok((true, self.plugins.last_mut().unwrap())); + // } + // Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), + // } + // } + // bail!("Plugin '{}' not found in {:?}", name, &paths) + // } } struct StaticPlugin

{ @@ -297,18 +425,15 @@ impl

StaticPlugin

{ } } -impl PluginInfo for StaticPlugin

+impl PluginLoader + for StaticPlugin

where P: Plugin, { - fn name(&self) -> &str { - P::STATIC_NAME - } - fn path(&self) -> &str { - "" - } - fn deletable(&self) -> bool { - false + fn load( + &self, + ) -> ZResult + Send + Sync>> { + Box::new(Self::new()) } } @@ -316,57 +441,45 @@ impl PluginStarter for St where P: Plugin, { - fn start(&self, args: &StartArgs) -> ZResult { - P::start(P::STATIC_NAME, args) - } - fn as_plugin_info(&self) -> &dyn PluginInfo { - self - } -} - -impl PluginInfo - for DynamicPlugin -{ - fn name(&self) -> &str { - &self.name - } - fn path(&self) -> &str { - self.path.to_str().unwrap() - } - fn deletable(&self) -> bool { - true + fn start(&self, name: &str, args: &StartArgs) -> ZResult { + P::start(name, args) } } impl PluginStarter for DynamicPlugin { - fn start(&self, args: &StartArgs) -> ZResult { - (self.vtable.start)(self.name(), args) - } - fn as_plugin_info(&self) -> &dyn PluginInfo { - self + fn start(&self, name: &str, args: &StartArgs) -> ZResult { + (self.vtable.start)(name, args) } } -struct +enum DynamicPluginLoader { + ByName((LibLoader, String)), + ByPaths((Vec)), +} -pub struct DynamicPlugin { - name: String, - lib: Option, - vtable: Option>, - path: Option, +impl PluginLoader for DynamicPluginLoader { + fn load( + &self, + ) -> ZResult + Send + Sync>> { + } +} + +struct DynamicPluginStarter { + path: PathBuf, + lib: Library, + vtable: PluginVTable, } impl - DynamicPlugin + DynamicPluginStarter { - pub fn new(name: String, lib: Library, path: PathBuf) -> Self { + pub fn new(path: PathBuf, lib: Library, vtable: PluginVTable) -> Self { Self { - name, - lib: None, - vtable: None, - path: None, + path, + lib, + vtable, } } @@ -448,4 +561,3 @@ impl } } -} diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index de6cef745f..89e6e6e54a 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -214,7 +214,7 @@ impl AdminSpace { rec.path() ); } - match rec.start(&admin.context.runtime) { + match rec.run(&admin.context.runtime) { Ok((true, rec)) => { active_plugins .insert(name.into(), rec.path().to_string()); diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 6a2bc0a682..fe9b6a473d 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -119,7 +119,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na req = if required { "required" } else { "" }, name = plugin.name() ); - match plugin.start(&runtime) { + match plugin.run(&runtime) { Ok(_) => { log::info!( "Successfully started plugin {} from {:?}", From 2c907166a4fac110a922272a87a1b839a7d652ec Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 4 Nov 2023 09:09:27 +0100 Subject: [PATCH 033/106] send + sync problem --- plugins/example-plugin/src/lib.rs | 4 +- plugins/example-storage-plugin/src/lib.rs | 4 +- plugins/zenoh-plugin-rest/src/lib.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 14 +- .../src/memory_backend/mod.rs | 2 +- plugins/zenoh-plugin-trait/src/lib.rs | 6 +- plugins/zenoh-plugin-trait/src/loading.rs | 464 +++++++++--------- plugins/zenoh-plugin-trait/src/vtable.rs | 3 +- zenoh/src/net/runtime/adminspace.rs | 4 +- zenoh/src/plugins/sealed.rs | 2 +- 10 files changed, 248 insertions(+), 257 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 5c865ac8e8..bed5b98e47 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -40,13 +40,13 @@ const DEFAULT_SELECTOR: &str = "demo/example/**"; impl ZenohPlugin for ExamplePlugin {} impl Plugin for ExamplePlugin { type StartArgs = Runtime; - type RunningPlugin = zenoh::plugins::RunningPlugin; + type Instance = zenoh::plugins::RunningPlugin; // A mandatory const to define, in case of the plugin is built as a standalone executable const STATIC_NAME: &'static str = "example"; // The first operation called by zenohd on the plugin - fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { + fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { let config = runtime.config().lock(); let self_cfg = config.plugin(name).unwrap().as_object().unwrap(); // get the plugin's config details from self_cfg Map (here the "storage-selector" property) diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index d0b9addafe..ef9c58d323 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -31,9 +31,9 @@ zenoh_plugin_trait::declare_plugin!(ExampleBackend); impl Plugin for ExampleBackend { type StartArgs = VolumeConfig; - type RunningPlugin = VolumePlugin; + type Instance = VolumePlugin; - fn start(_name: &str, _args: &Self::StartArgs) -> ZResult { + fn start(_name: &str, _args: &Self::StartArgs) -> ZResult { let volume = ExampleBackend {}; Ok(Box::new(volume)) } diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index f122011495..3cb12d290d 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -215,7 +215,7 @@ impl ZenohPlugin for RestPlugin {} impl Plugin for RestPlugin { type StartArgs = Runtime; - type RunningPlugin = zenoh::plugins::RunningPlugin; + type Instance = zenoh::plugins::RunningPlugin; const STATIC_NAME: &'static str = "rest"; fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 466253a4d6..27e61be28b 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -58,9 +58,9 @@ impl Plugin for StoragesPlugin { const STATIC_NAME: &'static str = "storage_manager"; type StartArgs = Runtime; - type RunningPlugin = zenoh::plugins::RunningPlugin; + type Instance = zenoh::plugins::RunningPlugin; - fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { + fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { std::mem::drop(env_logger::try_init()); log::debug!("StorageManager plugin {}", LONG_VERSION.as_str()); let config = @@ -109,7 +109,7 @@ impl StorageRuntimeInner { let session = Arc::new(zenoh::init(runtime.clone()).res_sync().unwrap()); let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX) - .add_static::(); + .add_static_plugin::(); let mut new_self = StorageRuntimeInner { name, @@ -190,12 +190,12 @@ impl StorageRuntimeInner { let volume_id = storage.volume_id.clone(); let backend = self.plugins_manager.running_plugin(&volume_id)?; let storage_name = storage.name.clone(); - let in_interceptor = backend.running().incoming_data_interceptor(); - let out_interceptor = backend.running().outgoing_data_interceptor(); + let in_interceptor = backend.instance().incoming_data_interceptor(); + let out_interceptor = backend.instance().outgoing_data_interceptor(); let stopper = async_std::task::block_on(create_and_start_storage( admin_key, storage, - backend.running(), + backend.instance(), in_interceptor, out_interceptor, self.session.clone(), @@ -270,7 +270,7 @@ impl RunningPluginTrait for StorageRuntime { { responses.push(zenoh::plugins::Response::new( key.clone(), - plugin.running().get_admin_status(), + plugin.instance().get_admin_status(), )) } }); diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index fb148da0e4..2ebe534f84 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -30,7 +30,7 @@ pub struct MemoryBackend { impl Plugin for MemoryBackend { type StartArgs = VolumeConfig; - type RunningPlugin = VolumePlugin; + type Instance = VolumePlugin; const STATIC_NAME: &'static str = MEMORY_BACKEND_NAME; diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 566e8d1127..8aa9ad0b53 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -51,14 +51,14 @@ pub trait CompatibilityVersion { pub trait PluginControl { fn plugins(&self) -> Vec<&str>; - fn status(&self, name: &str) -> PluginStatus; + // fn status(&self, name: &str) -> PluginStatus; } pub trait Plugin: Sized + 'static { type StartArgs: CompatibilityVersion; - type RunningPlugin: CompatibilityVersion; + type Instance: CompatibilityVersion; /// Your plugins' default name when statically linked. const STATIC_NAME: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure - fn start(name: &str, args: &Self::StartArgs) -> ZResult; + fn start(name: &str, args: &Self::StartArgs) -> ZResult; } diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 2f068817cb..985a3181f4 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -13,8 +13,11 @@ // use crate::*; use libloading::Library; -use serde_json::de; -use std::path::PathBuf; +use std::{ + borrow::Cow, + marker::PhantomData, + path::{Path, PathBuf}, +}; use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; use zenoh_result::{bail, ZResult}; use zenoh_util::LibLoader; @@ -23,53 +26,57 @@ use zenoh_util::LibLoader; pub enum PluginState { Declared, Loaded, - Runnning, + Running, } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum PluginCondition { Ok, - Warning(String), - Error(String), + Warning(Cow<'static, str>), + Error(Cow<'static, str>), } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct PluginStatus { pub state: PluginState, pub condition: PluginCondition, } -trait PluginLoader { - fn load( - &self, - ) -> ZResult + Send + Sync>>; -} +// trait PluginLoader { +// fn load(&self) -> ZResult>>; +// } -trait PluginStarter { - fn start(&self, name: &str, args: &StartArgs) -> ZResult; +trait PluginLoader { + fn load(&self) -> ZResult>; } +trait PluginStarter { + fn start(&self, name: &str, args: &StartArgs) -> ZResult; + fn path(&self) -> &str; +} -struct PluginRecord { +struct PluginRecord { name: String, - path: Option, condition: PluginCondition, - loader: Box + Send + Sync>, - starter: Option + Send + Sync>>, - running_plugin: Option, + loader: + Box + Send + Sync> + Send + Sync>, + starter: Option + Send + Sync>>, + instance: Option, } -impl - PluginRecord +impl + PluginRecord { - fn new + Send + Sync + 'static>(name: String, loader: S) -> Self { + fn new + 'static + Send + Sync>( + name: String, + loader: T, + ) -> Self { Self { name, - path: None, condition: PluginCondition::Ok, - loader, + loader: Box::new(loader), starter: None, - running_plugin: None, + instance: None, } } } @@ -80,17 +87,19 @@ pub trait PluginInfo { fn status(&self) -> PluginStatus; } -impl PluginInfo for PluginRecord { +impl PluginInfo + for PluginRecord +{ fn name(&self) -> &str { self.name.as_str() } fn path(&self) -> &str { - self.path.map_or("", |v| v.path()) + self.starter.as_ref().map_or("", |v| v.path()) } fn status(&self) -> PluginStatus { PluginStatus { state: if self.starter.is_some() { - if self.running_plugin.is_some() { + if self.instance.is_some() { PluginState::Running } else { PluginState::Loaded @@ -98,21 +107,23 @@ impl Plugi } else { PluginState::Declared }, - condition: self.condition, + condition: self.condition.clone(), } } } -pub trait DeclaredPluginRecord : PluginInfo { - fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)>; - fn loaded(&self) -> Option<&dyn LoadedPluginRecord>; - fn loaded_mut( - &mut self - ) -> Option<&mut dyn LoadedPluginRecord>; +pub trait DeclaredPluginRecord: + PluginInfo +{ + fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)>; + fn loaded(&self) -> Option<&dyn LoadedPluginRecord>; + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPluginRecord>; } -impl DeclaredPluginRecord for PluginRecord { - fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)> { +impl + DeclaredPluginRecord for PluginRecord +{ + fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)> { if self.starter.is_some() { Ok((false, self)) } else { @@ -123,22 +134,20 @@ impl Decla Ok((true, self)) } Err(e) => { - self.condition = PluginCondition::Error(format!("{}", e)); + self.condition = PluginCondition::Error(e.to_string().into()); Err(e) } } } } - fn loaded(&self) -> Option<&dyn LoadedPluginRecord> { + fn loaded(&self) -> Option<&dyn LoadedPluginRecord> { if self.starter.is_some() { Some(self) } else { None } } - fn loaded_mut( - &mut self - ) -> Option<&mut dyn LoadedPluginRecord> { + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPluginRecord> { if self.starter.is_some() { Some(self) } else { @@ -147,35 +156,43 @@ impl Decla } } -pub trait LoadedPluginRecord : PluginInfo +pub trait LoadedPluginRecord: + PluginInfo { - fn run(&mut self, args: &StartArgs) -> ZResult; - fn running(&self) -> Option<&dyn RunningPluginRecord>; - pub fn running_mut( - &mut self - ) -> Option<&mut dyn RunningPluginRecord>; + fn run( + &mut self, + args: &StartArgs, + ) -> ZResult<&mut dyn RunningPluginRecord>; + fn running(&self) -> Option<&dyn RunningPluginRecord>; + fn running_mut(&mut self) -> Option<&mut dyn RunningPluginRecord>; } -impl LoadedPluginRecord for PluginRecord { - fn run(&mut self, args: &StartArgs) -> ZResult { - let starter = self.starter.as_ref().ok_or_else(|| format!("Plugin `{}` not loaded", self.name))?; - let already_running = self.running_plugin.is_some(); +impl + LoadedPluginRecord for PluginRecord +{ + fn run( + &mut self, + args: &StartArgs, + ) -> ZResult<&mut dyn RunningPluginRecord> { + let starter = self + .starter + .as_ref() + .ok_or_else(|| format!("Plugin `{}` not loaded", self.name))?; + let already_running = self.instance.is_some(); if !already_running { - self.running_plugin = Some(starter.start(self.name(), args)?); + self.instance = Some(starter.start(self.name(), args)?); } - Ok(self.running_plugin.as_ref().unwrap().clone()) + Ok(self) } - fn running(&self) -> Option<&dyn RunningPluginRecord> { - if self.running_plugin.is_some() { + fn running(&self) -> Option<&dyn RunningPluginRecord> { + if self.instance.is_some() { Some(self) } else { None } } - fn running_mut( - &mut self - ) -> Option<&mut dyn RunningPluginRecord> { - if self.running_plugin.is_some() { + fn running_mut(&mut self) -> Option<&mut dyn RunningPluginRecord> { + if self.instance.is_some() { Some(self) } else { None @@ -183,37 +200,36 @@ impl Load } } -pub trait RunningPluginRecord -{ +pub trait RunningPluginRecord { fn stop(&mut self); - fn running(&self) -> &RunningPlugin; - fn running_mut(&mut self) -> &mut RunningPlugin; + fn instance(&self) -> &Instance; + fn instance_mut(&mut self) -> &mut Instance; } -impl - RunningPluginRecord for PluginRecord +impl + RunningPluginRecord for PluginRecord { fn stop(&mut self) { - self.running_plugin = None; + self.instance = None; } - fn running(&self) -> &RunningPligin { - self.running_plugin.as_ref().unwrap() + fn instance(&self) -> &Instance { + self.instance.as_ref().unwrap() } - fn running_mut(&mut self) -> &mut RunningPligin { - self.running_plugin.as_mut().unwrap() + fn instance_mut(&mut self) -> &mut Instance { + self.instance.as_mut().unwrap() } } /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. -pub struct PluginsManager { +pub struct PluginsManager { default_lib_prefix: String, loader: Option, - plugins: Vec>, + plugins: Vec>, } -impl - PluginsManager +impl + PluginsManager { /// Constructs a new plugin manager with dynamic library loading enabled. pub fn dynamic>(loader: LibLoader, default_lib_prefix: S) -> Self { @@ -233,17 +249,52 @@ impl + Send + Sync, + pub fn add_static_plugin< + P: Plugin + Send + Sync, >( mut self, ) -> Self { let plugin_loader: StaticPlugin

= StaticPlugin::new(); let name = P::STATIC_NAME.into(); - self.plugins.push(PluginRecord::new(name, Box::new(plugin_loader))); + self.plugins.push(PluginRecord::new(name, plugin_loader)); self } + fn add_dynamic + 'static>( + &mut self, + name: String, + loader: L, + ) -> &mut dyn DeclaredPluginRecord { + self.plugins.push(PluginRecord::new(name, loader)); + self.plugins.last_mut().unwrap() + } + + /// Add dynamic plugin to the manager by name, automatically prepending the default library prefix + pub fn add_dynamic_plugin_by_name>( + &mut self, + name: S, + plugin_name: &str, + ) -> ZResult<&dyn DeclaredPluginRecord> { + let plugin_name = format!("{}{}", self.default_lib_prefix, plugin_name); + let libloader = self + .loader + .as_ref() + .ok_or("Dynamic plugin loading is disabled")? + .clone(); + let loader = DynamicPluginLoader::by_name(libloader, plugin_name); + Ok(self.add_dynamic(name.into(), loader)) + } + + /// Add first available dynamic plugin from the list of paths to the plugin files + pub fn add_dynamic_plugin_by_paths, P: AsRef + std::fmt::Debug>( + &mut self, + name: S, + paths: &[P], + ) -> ZResult<&dyn DeclaredPluginRecord> { + let loader = DynamicPluginLoader::by_paths(paths); + Ok(self.add_dynamic(name.into(), loader)) + } + /// Returns plugin index by name fn get_plugin_index(&self, name: &str) -> Option { self.plugins.iter().position(|p| p.name() == name) @@ -256,47 +307,53 @@ impl impl Iterator> + '_ { - self.plugins.iter() + pub fn plugins( + &self, + ) -> impl Iterator> + '_ { + self.plugins + .iter() + .map(|p| p as &dyn DeclaredPluginRecord) } /// Lists all plugins mutable pub fn plugins_mut( &mut self, - ) -> impl Iterator> + '_ { - self.plugins.iter_mut() + ) -> impl Iterator> + '_ { + self.plugins + .iter_mut() + .map(|p| p as &mut dyn DeclaredPluginRecord) } /// Lists the loaded plugins pub fn loaded_plugins( &self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.plugins().filter_map(|p| p.loaded()) } /// Lists the loaded plugins mutable pub fn loaded_plugins_mut( &mut self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.plugins_mut().filter_map(|p| p.loaded_mut()) } /// Lists the running plugins pub fn running_plugins( &self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.loaded_plugins().filter_map(|p| p.running()) } /// Lists the running plugins mutable pub fn running_plugins_mut( &mut self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.loaded_plugins_mut().filter_map(|p| p.running_mut()) } /// Returns single plugin record - pub fn plugin(&self, name: &str) -> ZResult<&dyn DeclaredPluginRecord> { + pub fn plugin(&self, name: &str) -> ZResult<&dyn DeclaredPluginRecord> { Ok(&self.plugins[self.get_plugin_index_err(name)?]) } @@ -304,7 +361,7 @@ impl ZResult<&mut DeclaredPluginRecord> { + ) -> ZResult<&mut dyn DeclaredPluginRecord> { let index = self.get_plugin_index_err(name)?; Ok(&mut self.plugins[index]) } @@ -313,7 +370,7 @@ impl ZResult<&dyn LoadedPluginRecord> { + ) -> ZResult<&dyn LoadedPluginRecord> { Ok(self .plugin(name)? .loaded() @@ -324,7 +381,7 @@ impl ZResult<&mut dyn LoadedPluginRecord> { + ) -> ZResult<&mut dyn LoadedPluginRecord> { Ok(self .plugin_mut(name)? .loaded_mut() @@ -335,7 +392,7 @@ impl ZResult<&dyn RunningPluginRecord> { + ) -> ZResult<&dyn RunningPluginRecord> { Ok(self .loaded_plugin(name)? .running() @@ -346,144 +403,93 @@ impl ZResult<&mut dyn RunningPluginRecord> { + ) -> ZResult<&mut dyn RunningPluginRecord> { Ok(self .loaded_plugin_mut(name)? .running_mut() .ok_or_else(|| format!("Plugin `{}` is not running", name))?) } - - // fn load_plugin( - // name: &str, - // lib: Library, - // path: PathBuf, - // ) -> ZResult> { - // DynamicPlugin::new(name.into(), lib, path) - // } - - // /// Tries to load a plugin with the name `defaukt_lib_prefix` + `backend_name` + `.so | .dll | .dylib` - // /// in lib_loader's search paths. - // /// Returns a tuple of (retval, plugin_record) - // /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded - // pub fn load_plugin_by_backend_name, T1: AsRef>( - // &mut self, - // name: T, - // backend_name: T1, - // ) -> ZResult<(bool, &mut PluginRecord)> { - // let name = name.as_ref(); - // if let Some(index) = self.get_plugin_index(name) { - // return Ok((false, &mut self.plugins[index])); - // } - // let backend_name = backend_name.as_ref(); - // let (lib, p) = match &mut self.loader { - // Some(l) => unsafe { l.search_and_load(&format!("{}{}", &self.default_lib_prefix, &backend_name))? }, - // None => bail!("Can't load dynamic plugin `{}`, as dynamic loading is not enabled for this plugin manager.", &name), - // }; - // let plugin = match Self::load_plugin(name, lib, p.clone()) { - // Ok(p) => p, - // Err(e) => bail!("After loading `{:?}`: {}", &p, e), - // }; - // self.plugins.push(PluginRecord::new(plugin)); - // Ok((true, self.plugins.last_mut().unwrap())) - // } - // /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) - // /// Returns a tuple of (retval, plugin_record) - // /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded - // pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( - // &mut self, - // name: T, - // paths: &[P], - // ) -> ZResult<(bool, &mut PluginRecord)> { - // let name = name.as_ref(); - // if let Some(index) = self.get_plugin_index(name) { - // return Ok((false, &mut self.plugins[index])); - // } - // for path in paths { - // let path = path.as_ref(); - // match unsafe { LibLoader::load_file(path) } { - // Ok((lib, p)) => { - // let plugin = Self::load_plugin(name, lib, p)?; - // self.plugins.push(PluginRecord::new(plugin)); - // return Ok((true, self.plugins.last_mut().unwrap())); - // } - // Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), - // } - // } - // bail!("Plugin '{}' not found in {:?}", name, &paths) - // } } struct StaticPlugin

{ - inner: std::marker::PhantomData

, + inner: PhantomData

, } impl

StaticPlugin

{ fn new() -> Self { - StaticPlugin { - inner: std::marker::PhantomData, - } + StaticPlugin { inner: PhantomData } } } -impl PluginLoader - for StaticPlugin

+impl + PluginLoader for StaticPlugin

where - P: Plugin, + P: Plugin, { - fn load( - &self, - ) -> ZResult + Send + Sync>> { - Box::new(Self::new()) + fn load(&self) -> ZResult>> { + Ok(Box::new(Self::new())) } } -impl PluginStarter for StaticPlugin

+impl PluginStarter for StaticPlugin

where - P: Plugin, + P: Plugin, { - fn start(&self, name: &str, args: &StartArgs) -> ZResult { + fn start(&self, name: &str, args: &StartArgs) -> ZResult { P::start(name, args) } -} - -impl - PluginStarter for DynamicPlugin -{ - fn start(&self, name: &str, args: &StartArgs) -> ZResult { - (self.vtable.start)(name, args) + fn path(&self) -> &str { + "" } } - -enum DynamicPluginLoader { - ByName((LibLoader, String)), - ByPaths((Vec)), +enum DynamicPluginSource { + /// Load plugin with the name in String + `.so | .dll | .dylib` + /// in LibLoader's search paths. + ByName((LibLoader, String)), + /// Load first avalilable plugin from the list of path to plugin files (absolute or relative to the current working directory) + ByPaths(Vec), } -impl PluginLoader for DynamicPluginLoader { - fn load( - &self, - ) -> ZResult + Send + Sync>> { +impl DynamicPluginSource { + fn load(&self) -> ZResult<(Library, PathBuf)> { + match self { + DynamicPluginSource::ByName((libloader, name)) => unsafe { + libloader.search_and_load(name) + }, + DynamicPluginSource::ByPaths(paths) => { + for path in paths { + match unsafe { LibLoader::load_file(path) } { + Ok((l, p)) => return Ok((l, p)), + Err(e) => log::warn!("Plugin {} load fail: {}", path, e), + } + } + bail!("Plugin not found in {:?}", &paths) + } + } } } -struct DynamicPluginStarter { - path: PathBuf, - lib: Library, - vtable: PluginVTable, +struct DynamicPluginLoader { + source: DynamicPluginSource, + _phantom: PhantomData<(StartArgs, Instance)>, } -impl - DynamicPluginStarter +impl + DynamicPluginLoader { - pub fn new(path: PathBuf, lib: Library, vtable: PluginVTable) -> Self { + fn by_name>(libloader: LibLoader, name: S) -> Self { Self { - path, - lib, - vtable, + source: DynamicPluginSource::ByName((libloader, name.into())), + _phantom: PhantomData, } } - - fn get_vtable(path: &PathBuf) -> ZResult> { + fn by_paths + std::fmt::Debug>(paths: &[P]) -> Self { + Self { + source: DynamicPluginSource::ByPaths(paths.iter().map(|p| p.as_ref().into()).collect()), + _phantom: PhantomData, + } + } + fn get_vtable(lib: &Library, path: &Path) -> ZResult> { log::debug!("Loading plugin {}", &path.to_str().unwrap(),); let get_plugin_loader_version = unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; @@ -498,7 +504,7 @@ impl } let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = Compatibility::new::(); + let host_compatibility_record = Compatibility::new::(); log::debug!( "Plugin compativilty record: {:?}", &plugin_compatibility_record @@ -511,53 +517,39 @@ impl ); } let load_plugin = - unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; + unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); Ok(vtable) } +} - /// Tries to load a plugin with the name `libname` + `.so | .dll | .dylib` - /// in lib_loader's search paths. - /// Returns a tuple of (retval, plugin_record) - /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded - fn load_by_libname( - &self, - libloader: &LibLoader, - libname: &str, - ) -> ZResult { - let (lib, p) = unsafe { libloader.search_and_load(libname)? }; - - let plugin = match Self::load_plugin(name, lib, p.clone()) { - Ok(p) => p, - Err(e) => bail!("After loading `{:?}`: {}", &p, e), - }; - self.plugins.push(PluginRecord::new(plugin)); - Ok((true, self.plugins.last_mut().unwrap())) - } - /// Tries to load a plugin from the list of path to plugin (absolute or relative to the current working directory) - /// Returns a tuple of (retval, plugin_record) - /// where `retval`` is true if the plugin was successfully loaded, false if pluginw with this name it was already loaded - pub fn load_plugin_by_paths, P: AsRef + std::fmt::Debug>( - &mut self, - name: T, - paths: &[P], - ) -> ZResult<(bool, &mut PluginRecord)> { - let name = name.as_ref(); - if let Some(index) = self.get_plugin_index(name) { - return Ok((false, &mut self.plugins[index])); - } - for path in paths { - let path = path.as_ref(); - match unsafe { LibLoader::load_file(path) } { - Ok((lib, p)) => { - let plugin = Self::load_plugin(name, lib, p)?; - self.plugins.push(PluginRecord::new(plugin)); - return Ok((true, self.plugins.last_mut().unwrap())); - } - Err(e) => log::warn!("Plugin '{}' load fail at {}: {}", &name, path, e), - } - } - bail!("Plugin '{}' not found in {:?}", name, &paths) +impl + PluginLoader for DynamicPluginLoader +{ + fn load(&self) -> ZResult>> { + let (lib, path) = self.source.load()?; + let vtable: PluginVTable = Self::get_vtable(&lib, &path)?; + Ok(Box::new(DynamicPluginStarter { + _lib: lib, + path, + vtable, + })) } } +struct DynamicPluginStarter { + _lib: Library, + path: PathBuf, + vtable: PluginVTable, +} + +impl + PluginStarter for DynamicPluginStarter +{ + fn start(&self, name: &str, args: &StartArgs) -> ZResult { + (self.vtable.start)(name, args) + } + fn path(&self) -> &str { + self.path.to_str().unwrap() + } +} diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index e1da1a579f..d9fa052709 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -166,8 +166,7 @@ impl Default for RustVersion { } impl PluginVTable { - pub fn new>( - ) -> Self { + pub fn new>() -> Self { Self { start: ConcretePlugin::start, } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 89e6e6e54a..5e0df31a77 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -74,7 +74,7 @@ impl ConfigValidator for AdminSpace { ) -> ZResult>> { let plugins_mgr = zlock!(self.context.plugins_mgr); let plugin = plugins_mgr.running_plugin(name)?; - plugin.running().config_checker(path, current, new) + plugin.instance().config_checker(path, current, new) } } @@ -676,7 +676,7 @@ fn plugins_status(context: &AdminContext, query: Query) { return; } match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - plugin.running().adminspace_getter(&selector, plugin_key) + plugin.instance().adminspace_getter(&selector, plugin_key) })) { Ok(Ok(responses)) => { for response in responses { diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 02768cd9b7..7eacbc0077 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -24,7 +24,7 @@ zconfigurable! { } /// Zenoh plugins should implement this trait to ensure type-safety, even if the starting arguments and expected plugin types change in a future release. -pub trait ZenohPlugin: Plugin {} +pub trait ZenohPlugin: Plugin {} /// A zenoh plugin receives a reference to a value of this type when started. pub type StartArgs = Runtime; From 9e6a2db32ddf2dd7fc6f6835b40f47a3ab61257a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 6 Nov 2023 14:38:19 +0100 Subject: [PATCH 034/106] unfinished --- plugins/zenoh-plugin-trait/src/loading.rs | 355 ++++++++++++++-------- 1 file changed, 226 insertions(+), 129 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 985a3181f4..0bd51942f3 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -36,59 +36,215 @@ pub enum PluginCondition { Error(Cow<'static, str>), } +impl PluginCondition { + fn store(&mut self, result: ZResult) -> ZResult { + match result { + Ok(v) => Ok(v), + Err(e) => { + *self = PluginCondition::Error(e.to_string().into()); + Err(e) + } + } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct PluginStatus { pub state: PluginState, pub condition: PluginCondition, } -// trait PluginLoader { -// fn load(&self) -> ZResult>>; -// } +pub trait PluginInfo { + fn name(&self) -> &str; + fn path(&self) -> &str; + fn status(&self) -> PluginStatus; +} -trait PluginLoader { - fn load(&self) -> ZResult>; +pub trait DeclaredPlugin: + PluginInfo +{ + fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin>; + fn loaded(&self) -> Option<&dyn LoadedPlugin>; + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin>; +} +pub trait LoadedPlugin: + PluginInfo +{ + fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin>; + fn running(&self) -> Option<&dyn RunningPlugin>; + fn running_mut(&mut self) -> Option<&mut dyn RunningPlugin>; } -trait PluginStarter { - fn start(&self, name: &str, args: &StartArgs) -> ZResult; - fn path(&self) -> &str; +pub trait RunningPlugin { + fn stop(&mut self); + fn instance(&self) -> &Instance; + fn instance_mut(&mut self) -> &mut Instance; +} + +struct StaticPlugin +where + P: Plugin, +{ + instance: Option, + phantom: PhantomData

, +} + +impl + StaticPlugin +where + P: Plugin, +{ + fn new() -> Self { + Self { + instance: None, + phantom: PhantomData, + } + } +} + +impl PluginInfo + for StaticPlugin +{ + fn name(&self) -> &str { + P::STATIC_NAME + } + fn path(&self) -> &str { + "" + } + fn status(&self) -> PluginStatus { + PluginStatus { + state: self + .instance + .map_or(PluginState::Loaded, |_| PluginState::Running), + condition: PluginCondition::Ok, // TODO: request runnnig plugin status + } + } +} + +impl + DeclaredPlugin for StaticPlugin +where + P: Plugin, +{ + fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { + Ok(self) + } + fn loaded(&self) -> Option<&dyn LoadedPlugin> { + Some(self) + } + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { + Some(self) + } +} + +impl + LoadedPlugin for StaticPlugin +where + P: Plugin, +{ + fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin> { + if self.instance.is_none() { + self.instance = Some(P::start(self.name(), args)?); + } + Ok(self) + } + fn running(&self) -> Option<&dyn RunningPlugin> { + if self.instance.is_some() { + Some(self) + } else { + None + } + } + fn running_mut(&mut self) -> Option<&mut dyn RunningPlugin> { + if self.instance.is_some() { + Some(self) + } else { + None + } + } +} + +impl + RunningPlugin for StaticPlugin +where + P: Plugin, +{ + fn stop(&mut self) {} + fn instance(&self) -> &Instance { + self.instance.as_ref().unwrap() + } + fn instance_mut(&mut self) -> &mut Instance { + self.instance.as_mut().unwrap() + } +} + +/// This enum contains information where to load the plugin from. +enum DynamicPluginSource { + /// Load plugin with the name in String + `.so | .dll | .dylib` + /// in LibLoader's search paths. + ByName((LibLoader, String)), + /// Load first avalilable plugin from the list of path to plugin files (absolute or relative to the current working directory) + ByPaths(Vec), +} + +impl DynamicPluginSource { + fn load(&self) -> ZResult<(Library, PathBuf)> { + match self { + DynamicPluginSource::ByName((libloader, name)) => unsafe { + libloader.search_and_load(name) + }, + DynamicPluginSource::ByPaths(paths) => { + for path in paths { + match unsafe { LibLoader::load_file(path) } { + Ok((l, p)) => return Ok((l, p)), + Err(e) => log::warn!("Plugin {} load fail: {}", path, e), + } + } + bail!("Plugin not found in {:?}", &paths) + } + } + } } -struct PluginRecord { +struct DynamicPluginStarter { + _lib: Library, + path: PathBuf, + vtable: PluginVTable, +} + +impl + DynamicPluginStarter +{ + fn new(lib: Library, path: PathBuf)`` + } +} + +struct DynamicPlugin { name: String, condition: PluginCondition, - loader: - Box + Send + Sync> + Send + Sync>, - starter: Option + Send + Sync>>, + source: DynamicPluginSource, + starter: Option>, instance: Option, } impl - PluginRecord + DynamicPlugin { - fn new + 'static + Send + Sync>( - name: String, - loader: T, - ) -> Self { + fn new(name: String, source: DynamicPluginSource) -> Self { Self { name, condition: PluginCondition::Ok, - loader: Box::new(loader), + source, starter: None, instance: None, } } } -pub trait PluginInfo { - fn name(&self) -> &str; - fn path(&self) -> &str; - fn status(&self) -> PluginStatus; -} + impl PluginInfo - for PluginRecord + for DynamicPlugin { fn name(&self) -> &str { self.name.as_str() @@ -107,26 +263,59 @@ impl PluginInfo } else { PluginState::Declared }, - condition: self.condition.clone(), + condition: self.condition.clone(), // TODO: request condition from running plugin } } } -pub trait DeclaredPluginRecord: - PluginInfo -{ - fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)>; - fn loaded(&self) -> Option<&dyn LoadedPluginRecord>; - fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPluginRecord>; +fn get_vtable( + lib: &Library, + path: &Path, +) -> ZResult> { + log::debug!("Loading plugin {}", &path.to_str().unwrap(),); + let get_plugin_loader_version = + unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; + let plugin_loader_version = get_plugin_loader_version(); + log::debug!("Plugin loader version: {}", &plugin_loader_version); + if plugin_loader_version != PLUGIN_LOADER_VERSION { + bail!( + "Plugin loader version mismatch: host = {}, plugin = {}", + PLUGIN_LOADER_VERSION, + plugin_loader_version + ); + } + let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; + let plugin_compatibility_record = get_compatibility(); + let host_compatibility_record = Compatibility::new::(); + log::debug!( + "Plugin compativilty record: {:?}", + &plugin_compatibility_record + ); + if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { + bail!( + "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", + host_compatibility_record, + plugin_compatibility_record + ); + } + let load_plugin = + unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; + let vtable = load_plugin(); + Ok(vtable) } + impl - DeclaredPluginRecord for PluginRecord + DeclaredPlugin for DynamicPlugin { - fn load(&mut self) -> ZResult<(bool, &mut dyn LoadedPluginRecord)> { + fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { if self.starter.is_some() { - Ok((false, self)) + Ok(self) } else { + let (lib, path) = self.source.load()?; + let starter = DynamicPluginStarter::new(lib, path)?; + + match self.loader.load() { Ok(starter) => { self.starter = Some(starter); @@ -156,17 +345,6 @@ impl } } -pub trait LoadedPluginRecord: - PluginInfo -{ - fn run( - &mut self, - args: &StartArgs, - ) -> ZResult<&mut dyn RunningPluginRecord>; - fn running(&self) -> Option<&dyn RunningPluginRecord>; - fn running_mut(&mut self) -> Option<&mut dyn RunningPluginRecord>; -} - impl LoadedPluginRecord for PluginRecord { @@ -200,12 +378,6 @@ impl } } -pub trait RunningPluginRecord { - fn stop(&mut self); - fn instance(&self) -> &Instance; - fn instance_mut(&mut self) -> &mut Instance; -} - impl RunningPluginRecord for PluginRecord { @@ -260,7 +432,9 @@ impl + 'static>( + fn add_dynamic< + L: PluginLoader + Send + Sync> + 'static + Send + Sync, + >( &mut self, name: String, loader: L, @@ -411,69 +585,6 @@ impl { - inner: PhantomData

, -} - -impl

StaticPlugin

{ - fn new() -> Self { - StaticPlugin { inner: PhantomData } - } -} - -impl - PluginLoader for StaticPlugin

-where - P: Plugin, -{ - fn load(&self) -> ZResult>> { - Ok(Box::new(Self::new())) - } -} - -impl PluginStarter for StaticPlugin

-where - P: Plugin, -{ - fn start(&self, name: &str, args: &StartArgs) -> ZResult { - P::start(name, args) - } - fn path(&self) -> &str { - "" - } -} -enum DynamicPluginSource { - /// Load plugin with the name in String + `.so | .dll | .dylib` - /// in LibLoader's search paths. - ByName((LibLoader, String)), - /// Load first avalilable plugin from the list of path to plugin files (absolute or relative to the current working directory) - ByPaths(Vec), -} - -impl DynamicPluginSource { - fn load(&self) -> ZResult<(Library, PathBuf)> { - match self { - DynamicPluginSource::ByName((libloader, name)) => unsafe { - libloader.search_and_load(name) - }, - DynamicPluginSource::ByPaths(paths) => { - for path in paths { - match unsafe { LibLoader::load_file(path) } { - Ok((l, p)) => return Ok((l, p)), - Err(e) => log::warn!("Plugin {} load fail: {}", path, e), - } - } - bail!("Plugin not found in {:?}", &paths) - } - } - } -} - -struct DynamicPluginLoader { - source: DynamicPluginSource, - _phantom: PhantomData<(StartArgs, Instance)>, -} - impl DynamicPluginLoader { @@ -523,20 +634,6 @@ impl } } -impl - PluginLoader for DynamicPluginLoader -{ - fn load(&self) -> ZResult>> { - let (lib, path) = self.source.load()?; - let vtable: PluginVTable = Self::get_vtable(&lib, &path)?; - Ok(Box::new(DynamicPluginStarter { - _lib: lib, - path, - vtable, - })) - } -} - struct DynamicPluginStarter { _lib: Library, path: PathBuf, From 57bec106b6e18117f516a5f0e08cb9acc151c49b Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 7 Nov 2023 18:05:03 +0100 Subject: [PATCH 035/106] unfinished --- plugins/zenoh-plugin-trait/src/loading.rs | 340 +++++++++------------- 1 file changed, 137 insertions(+), 203 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 0bd51942f3..28e574c344 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -29,23 +29,42 @@ pub enum PluginState { Running, } -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum PluginCondition { - Ok, - Warning(Cow<'static, str>), - Error(Cow<'static, str>), +#[derive(Clone, Debug, PartialEq, Eq, Default)] +pub struct PluginCondition { + warnings: Vec>, + errors: Vec>, } impl PluginCondition { - fn store(&mut self, result: ZResult) -> ZResult { - match result { + pub fn new() -> Self { + Self::default() + } + pub fn clear(&mut self) { + self.warnings.clear(); + self.errors.clear(); + } + pub fn add_error>>(&mut self, error: S) { + self.errors.push(error.into()); + } + pub fn add_warning>>(&mut self, warning: S) { + self.warnings.push(warning.into()); + } + pub fn catch_error ZResult>(&mut self, f: F) -> ZResult { + self.clear(); + match f() { Ok(v) => Ok(v), Err(e) => { - *self = PluginCondition::Error(e.to_string().into()); + self.add_error(format!("{}", e)); Err(e) } } } + pub fn errors(&self) -> &[Cow<'static, str>] { + &self.errors + } + pub fn warnings(&self) -> &[Cow<'static, str>] { + &self.warnings + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -104,6 +123,8 @@ where impl PluginInfo for StaticPlugin +where + P: Plugin, { fn name(&self) -> &str { P::STATIC_NAME @@ -116,7 +137,7 @@ impl PluginI state: self .instance .map_or(PluginState::Loaded, |_| PluginState::Running), - condition: PluginCondition::Ok, // TODO: request runnnig plugin status + condition: PluginCondition::new(), // TODO: request runnnig plugin status } } } @@ -215,7 +236,51 @@ struct DynamicPluginStarter DynamicPluginStarter { - fn new(lib: Library, path: PathBuf)`` + fn get_vtable(lib: &Library, path: &Path) -> ZResult> { + log::debug!("Loading plugin {}", &path.to_str().unwrap(),); + let get_plugin_loader_version = + unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; + let plugin_loader_version = get_plugin_loader_version(); + log::debug!("Plugin loader version: {}", &plugin_loader_version); + if plugin_loader_version != PLUGIN_LOADER_VERSION { + bail!( + "Plugin loader version mismatch: host = {}, plugin = {}", + PLUGIN_LOADER_VERSION, + plugin_loader_version + ); + } + let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; + let plugin_compatibility_record = get_compatibility(); + let host_compatibility_record = Compatibility::new::(); + log::debug!( + "Plugin compativilty record: {:?}", + &plugin_compatibility_record + ); + if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { + bail!( + "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", + host_compatibility_record, + plugin_compatibility_record + ); + } + let load_plugin = + unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; + let vtable = load_plugin(); + Ok(vtable) + } + fn new(lib: Library, path: PathBuf) -> ZResult { + let vtable = Self::get_vtable(&lib, &path)?; + Ok(Self { + _lib: lib, + path, + vtable, + }) + } + fn start(&self, name: &str, args: &StartArgs) -> ZResult { + (self.vtable.start)(name, args) + } + fn path(&self) -> &str { + self.path.to_str().unwrap() } } @@ -233,7 +298,7 @@ impl fn new(name: String, source: DynamicPluginSource) -> Self { Self { name, - condition: PluginCondition::Ok, + condition: PluginCondition::new(), source, starter: None, instance: None, @@ -241,8 +306,6 @@ impl } } - - impl PluginInfo for DynamicPlugin { @@ -268,75 +331,27 @@ impl PluginInfo } } -fn get_vtable( - lib: &Library, - path: &Path, -) -> ZResult> { - log::debug!("Loading plugin {}", &path.to_str().unwrap(),); - let get_plugin_loader_version = - unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; - let plugin_loader_version = get_plugin_loader_version(); - log::debug!("Plugin loader version: {}", &plugin_loader_version); - if plugin_loader_version != PLUGIN_LOADER_VERSION { - bail!( - "Plugin loader version mismatch: host = {}, plugin = {}", - PLUGIN_LOADER_VERSION, - plugin_loader_version - ); - } - let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; - let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = Compatibility::new::(); - log::debug!( - "Plugin compativilty record: {:?}", - &plugin_compatibility_record - ); - if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { - bail!( - "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", - host_compatibility_record, - plugin_compatibility_record - ); - } - let load_plugin = - unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; - let vtable = load_plugin(); - Ok(vtable) -} - - impl DeclaredPlugin for DynamicPlugin { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { - if self.starter.is_some() { - Ok(self) - } else { - let (lib, path) = self.source.load()?; - let starter = DynamicPluginStarter::new(lib, path)?; - - - match self.loader.load() { - Ok(starter) => { - self.starter = Some(starter); - self.condition = PluginCondition::Ok; - Ok((true, self)) - } - Err(e) => { - self.condition = PluginCondition::Error(e.to_string().into()); - Err(e) - } - } + if self.starter.is_none() { + self.condition.catch_error(|| { + let (lib, path) = self.source.load()?; + self.starter = Some(DynamicPluginStarter::new(lib, path)?); + Ok(()) + })?; } + Ok(self) } - fn loaded(&self) -> Option<&dyn LoadedPluginRecord> { + fn loaded(&self) -> Option<&dyn LoadedPlugin> { if self.starter.is_some() { Some(self) } else { None } } - fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPluginRecord> { + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { if self.starter.is_some() { Some(self) } else { @@ -346,30 +361,30 @@ impl } impl - LoadedPluginRecord for PluginRecord + LoadedPlugin for DynamicPlugin { - fn run( - &mut self, - args: &StartArgs, - ) -> ZResult<&mut dyn RunningPluginRecord> { - let starter = self - .starter - .as_ref() - .ok_or_else(|| format!("Plugin `{}` not loaded", self.name))?; - let already_running = self.instance.is_some(); - if !already_running { - self.instance = Some(starter.start(self.name(), args)?); - } + fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin> { + self.condition.catch_error(|| { + let starter = self + .starter + .as_ref() + .ok_or_else(|| format!("Plugin `{}` not loaded", self.name))?; + let already_running = self.instance.is_some(); + if !already_running { + self.instance = Some(starter.start(self.name(), args)?); + } + Ok(()) + })?; Ok(self) } - fn running(&self) -> Option<&dyn RunningPluginRecord> { + fn running(&self) -> Option<&dyn RunningPlugin> { if self.instance.is_some() { Some(self) } else { None } } - fn running_mut(&mut self) -> Option<&mut dyn RunningPluginRecord> { + fn running_mut(&mut self) -> Option<&mut dyn RunningPlugin> { if self.instance.is_some() { Some(self) } else { @@ -379,7 +394,7 @@ impl } impl - RunningPluginRecord for PluginRecord + RunningPlugin for DynamicPlugin { fn stop(&mut self) { self.instance = None; @@ -397,7 +412,7 @@ impl pub struct PluginsManager { default_lib_prefix: String, loader: Option, - plugins: Vec>, + plugins: Vec>>, } impl @@ -426,37 +441,31 @@ impl( mut self, ) -> Self { - let plugin_loader: StaticPlugin

= StaticPlugin::new(); - let name = P::STATIC_NAME.into(); - self.plugins.push(PluginRecord::new(name, plugin_loader)); + let plugin_loader: StaticPlugin = StaticPlugin::new(); + self.plugins.push(Box::new(plugin_loader)); self } - fn add_dynamic< - L: PluginLoader + Send + Sync> + 'static + Send + Sync, - >( - &mut self, - name: String, - loader: L, - ) -> &mut dyn DeclaredPluginRecord { - self.plugins.push(PluginRecord::new(name, loader)); - self.plugins.last_mut().unwrap() - } - /// Add dynamic plugin to the manager by name, automatically prepending the default library prefix pub fn add_dynamic_plugin_by_name>( &mut self, name: S, plugin_name: &str, - ) -> ZResult<&dyn DeclaredPluginRecord> { + ) -> ZResult<&mut dyn DeclaredPlugin> { let plugin_name = format!("{}{}", self.default_lib_prefix, plugin_name); let libloader = self .loader .as_ref() .ok_or("Dynamic plugin loading is disabled")? .clone(); - let loader = DynamicPluginLoader::by_name(libloader, plugin_name); - Ok(self.add_dynamic(name.into(), loader)) + let loader = DynamicPlugin::new( + plugin_name, + DynamicPluginSource::ByName((libloader, plugin_name)), + ); + self.plugins.push(Box::new(loader)); + let plugin = self.plugins.last_mut().unwrap(); + let plugin = plugin as &mut dyn DeclaredPlugin; + Ok(plugin) } /// Add first available dynamic plugin from the list of paths to the plugin files @@ -464,70 +473,67 @@ impl ZResult<&dyn DeclaredPluginRecord> { - let loader = DynamicPluginLoader::by_paths(paths); - Ok(self.add_dynamic(name.into(), loader)) + ) -> ZResult<&mut dyn DeclaredPlugin> { + let name = name.into(); + let paths = paths.iter().map(|p| p.as_ref().into()).collect(); + let loader = DynamicPlugin::new(name, DynamicPluginSource::ByPaths(paths)); + self.plugins.push(Box::new(loader)); + let plugin = self.plugins.last_mut().unwrap(); + let plugin = plugin as &mut dyn DeclaredPlugin; + Ok(plugin) } - /// Returns plugin index by name fn get_plugin_index(&self, name: &str) -> Option { self.plugins.iter().position(|p| p.name() == name) } - /// Returns plugin index by name or error if plugin not found fn get_plugin_index_err(&self, name: &str) -> ZResult { self.get_plugin_index(name) .ok_or_else(|| format!("Plugin `{}` not found", name).into()) } /// Lists all plugins - pub fn plugins( - &self, - ) -> impl Iterator> + '_ { - self.plugins - .iter() - .map(|p| p as &dyn DeclaredPluginRecord) + pub fn plugins(&self) -> impl Iterator> + '_ { + self.plugins.iter().map(|p| p.as_ref()) } /// Lists all plugins mutable - pub fn plugins_mut( - &mut self, - ) -> impl Iterator> + '_ { - self.plugins - .iter_mut() - .map(|p| p as &mut dyn DeclaredPluginRecord) + pub fn plugins_mut<'a>( + &'a mut self, + ) -> impl Iterator+'a )> + 'a { + self.plugins.iter_mut().map(move|p| p.as_mut()) } /// Lists the loaded plugins pub fn loaded_plugins( &self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.plugins().filter_map(|p| p.loaded()) } /// Lists the loaded plugins mutable pub fn loaded_plugins_mut( &mut self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.plugins_mut().filter_map(|p| p.loaded_mut()) } /// Lists the running plugins pub fn running_plugins( &self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.loaded_plugins().filter_map(|p| p.running()) } /// Lists the running plugins mutable pub fn running_plugins_mut( &mut self, - ) -> impl Iterator> + '_ { + ) -> impl Iterator> + '_ { self.loaded_plugins_mut().filter_map(|p| p.running_mut()) } /// Returns single plugin record - pub fn plugin(&self, name: &str) -> ZResult<&dyn DeclaredPluginRecord> { + pub fn plugin(&self, name: &str) -> ZResult<&dyn DeclaredPlugin> { Ok(&self.plugins[self.get_plugin_index_err(name)?]) } @@ -535,16 +541,13 @@ impl ZResult<&mut dyn DeclaredPluginRecord> { + ) -> ZResult<&mut dyn DeclaredPlugin> { let index = self.get_plugin_index_err(name)?; Ok(&mut self.plugins[index]) } /// Returns loaded plugin record - pub fn loaded_plugin( - &self, - name: &str, - ) -> ZResult<&dyn LoadedPluginRecord> { + pub fn loaded_plugin(&self, name: &str) -> ZResult<&dyn LoadedPlugin> { Ok(self .plugin(name)? .loaded() @@ -555,7 +558,7 @@ impl ZResult<&mut dyn LoadedPluginRecord> { + ) -> ZResult<&mut dyn LoadedPlugin> { Ok(self .plugin_mut(name)? .loaded_mut() @@ -563,10 +566,7 @@ impl ZResult<&dyn RunningPluginRecord> { + pub fn running_plugin(&self, name: &str) -> ZResult<&dyn RunningPlugin> { Ok(self .loaded_plugin(name)? .running() @@ -577,76 +577,10 @@ impl ZResult<&mut dyn RunningPluginRecord> { + ) -> ZResult<&mut dyn RunningPlugin> { Ok(self .loaded_plugin_mut(name)? .running_mut() .ok_or_else(|| format!("Plugin `{}` is not running", name))?) } } - -impl - DynamicPluginLoader -{ - fn by_name>(libloader: LibLoader, name: S) -> Self { - Self { - source: DynamicPluginSource::ByName((libloader, name.into())), - _phantom: PhantomData, - } - } - fn by_paths + std::fmt::Debug>(paths: &[P]) -> Self { - Self { - source: DynamicPluginSource::ByPaths(paths.iter().map(|p| p.as_ref().into()).collect()), - _phantom: PhantomData, - } - } - fn get_vtable(lib: &Library, path: &Path) -> ZResult> { - log::debug!("Loading plugin {}", &path.to_str().unwrap(),); - let get_plugin_loader_version = - unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; - let plugin_loader_version = get_plugin_loader_version(); - log::debug!("Plugin loader version: {}", &plugin_loader_version); - if plugin_loader_version != PLUGIN_LOADER_VERSION { - bail!( - "Plugin loader version mismatch: host = {}, plugin = {}", - PLUGIN_LOADER_VERSION, - plugin_loader_version - ); - } - let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; - let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = Compatibility::new::(); - log::debug!( - "Plugin compativilty record: {:?}", - &plugin_compatibility_record - ); - if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { - bail!( - "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", - host_compatibility_record, - plugin_compatibility_record - ); - } - let load_plugin = - unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; - let vtable = load_plugin(); - Ok(vtable) - } -} - -struct DynamicPluginStarter { - _lib: Library, - path: PathBuf, - vtable: PluginVTable, -} - -impl - PluginStarter for DynamicPluginStarter -{ - fn start(&self, name: &str, args: &StartArgs) -> ZResult { - (self.vtable.start)(name, args) - } - fn path(&self) -> &str { - self.path.to_str().unwrap() - } -} From 4e63949b0a5456188965c2204f8957ee591787a1 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 7 Nov 2023 23:56:20 +0100 Subject: [PATCH 036/106] compilation errors fixed --- plugins/zenoh-plugin-trait/src/loading.rs | 128 +++++++++++++++------- 1 file changed, 86 insertions(+), 42 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 28e574c344..cfcd60a69f 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -49,16 +49,6 @@ impl PluginCondition { pub fn add_warning>>(&mut self, warning: S) { self.warnings.push(warning.into()); } - pub fn catch_error ZResult>(&mut self, f: F) -> ZResult { - self.clear(); - match f() { - Ok(v) => Ok(v), - Err(e) => { - self.add_error(format!("{}", e)); - Err(e) - } - } - } pub fn errors(&self) -> &[Cow<'static, str>] { &self.errors } @@ -67,6 +57,19 @@ impl PluginCondition { } } +pub trait PluginConditionAddError { + fn add_error(self, condition: &mut PluginCondition) -> Self; +} + +impl PluginConditionAddError for core::result::Result { + fn add_error(self, condition: &mut PluginCondition) -> Self { + if let Err(e) = &self { + condition.add_error(e.to_string()); + } + self + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct PluginStatus { pub state: PluginState, @@ -136,6 +139,7 @@ where PluginStatus { state: self .instance + .as_ref() .map_or(PluginState::Loaded, |_| PluginState::Running), condition: PluginCondition::new(), // TODO: request runnnig plugin status } @@ -336,11 +340,9 @@ impl { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { if self.starter.is_none() { - self.condition.catch_error(|| { - let (lib, path) = self.source.load()?; - self.starter = Some(DynamicPluginStarter::new(lib, path)?); - Ok(()) - })?; + let (lib, path) = self.source.load().add_error(&mut self.condition)?; + let starter = DynamicPluginStarter::new(lib, path).add_error(&mut self.condition)?; + self.starter = Some(starter); } Ok(self) } @@ -364,17 +366,18 @@ impl LoadedPlugin for DynamicPlugin { fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin> { - self.condition.catch_error(|| { - let starter = self - .starter - .as_ref() - .ok_or_else(|| format!("Plugin `{}` not loaded", self.name))?; - let already_running = self.instance.is_some(); - if !already_running { - self.instance = Some(starter.start(self.name(), args)?); - } - Ok(()) - })?; + let starter = self + .starter + .as_ref() + .ok_or_else(|| format!("Plugin `{}` not loaded", self.name)) + .add_error(&mut self.condition)?; + let already_running = self.instance.is_some(); + if !already_running { + let instance = starter + .start(self.name(), args) + .add_error(&mut self.condition)?; + self.instance = Some(instance); + } Ok(self) } fn running(&self) -> Option<&dyn RunningPlugin> { @@ -407,12 +410,52 @@ impl } } +struct PluginRecord( + Box>, +); + +impl + PluginRecord +{ + fn new + 'static>(plugin: P) -> Self { + Self(Box::new(plugin)) + } +} + +impl PluginInfo + for PluginRecord +{ + fn name(&self) -> &str { + self.0.name() + } + fn path(&self) -> &str { + self.0.path() + } + fn status(&self) -> PluginStatus { + self.0.status() + } +} + +impl + DeclaredPlugin for PluginRecord +{ + fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { + self.0.load() + } + fn loaded(&self) -> Option<&dyn LoadedPlugin> { + self.0.loaded() + } + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { + self.0.loaded_mut() + } +} + /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. pub struct PluginsManager { default_lib_prefix: String, loader: Option, - plugins: Vec>>, + plugins: Vec>, } impl @@ -442,7 +485,7 @@ impl Self { let plugin_loader: StaticPlugin = StaticPlugin::new(); - self.plugins.push(Box::new(plugin_loader)); + self.plugins.push(PluginRecord::new(plugin_loader)); self } @@ -459,13 +502,11 @@ impl; - Ok(plugin) + self.plugins.push(PluginRecord::new(loader)); + Ok(self.plugins.last_mut().unwrap()) } /// Add first available dynamic plugin from the list of paths to the plugin files @@ -477,10 +518,8 @@ impl; - Ok(plugin) + self.plugins.push(PluginRecord::new(loader)); + Ok(self.plugins.last_mut().unwrap()) } fn get_plugin_index(&self, name: &str) -> Option { @@ -494,14 +533,18 @@ impl impl Iterator> + '_ { - self.plugins.iter().map(|p| p.as_ref()) + self.plugins + .iter() + .map(|p| p as &dyn DeclaredPlugin) } /// Lists all plugins mutable - pub fn plugins_mut<'a>( - &'a mut self, - ) -> impl Iterator+'a )> + 'a { - self.plugins.iter_mut().map(move|p| p.as_mut()) + pub fn plugins_mut( + &mut self, + ) -> impl Iterator> + '_ { + self.plugins + .iter_mut() + .map(|p| p as &mut dyn DeclaredPlugin) } /// Lists the loaded plugins @@ -515,6 +558,7 @@ impl impl Iterator> + '_ { + // self.plugins_mut().filter_map(|p| p.loaded_mut()) self.plugins_mut().filter_map(|p| p.loaded_mut()) } From 2ccb9dd785c64841012c219d6e3a9ca4a18ce3b2 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 8 Nov 2023 18:03:19 +0100 Subject: [PATCH 037/106] compiles --- .../zenoh-plugin-storage-manager/src/lib.rs | 23 ++-- plugins/zenoh-plugin-trait/src/loading.rs | 106 ++++++++-------- plugins/zenoh-plugin-trait/src/vtable.rs | 34 ++--- zenoh/src/net/runtime/adminspace.rs | 117 ++++++++++-------- zenohd/src/main.rs | 36 +++++- 5 files changed, 172 insertions(+), 144 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 27e61be28b..9a0c88121b 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -155,20 +155,23 @@ impl StorageRuntimeInner { .map(|s| async move { s.send(StorageMessage::Stop) }), )); } - self.plugins_manager.running_plugin_mut(name)?.stop(); + self.plugins_manager.started_plugin_mut(name).ok_or(format!( + "Cannot find volume {} to stop it", + name + ))?.stop(); Ok(()) } fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); - if let Some(paths) = config.paths() { - self.plugins_manager - .load_plugin_by_paths(volume_id, paths)?; + let declared = if let Some(paths) = config.paths() { + self.plugins_manager.add_dynamic_plugin_by_paths(volume_id, paths)? } else { self.plugins_manager - .load_plugin_by_backend_name(volume_id, backend_name)?; - } - self.plugins_manager.plugin_mut(volume_id)?.run(&config)?; + .add_dynamic_plugin_by_name(volume_id, backend_name)? + }; + let loaded = declared.load()?; + loaded.start(&config)?; Ok(()) } fn kill_storage(&mut self, config: StorageConfig) { @@ -188,7 +191,9 @@ impl StorageRuntimeInner { fn spawn_storage(&mut self, storage: StorageConfig) -> ZResult<()> { let admin_key = self.status_key() + "/storages/" + &storage.name; let volume_id = storage.volume_id.clone(); - let backend = self.plugins_manager.running_plugin(&volume_id)?; + let backend = self.plugins_manager.started_plugin(&volume_id).ok_or( + format!("Cannot find volume {} to spawn storage {}", volume_id, storage.name), + )?; let storage_name = storage.name.clone(); let in_interceptor = backend.instance().incoming_data_interceptor(); let out_interceptor = backend.instance().outgoing_data_interceptor(); @@ -251,7 +256,7 @@ impl RunningPluginTrait for StorageRuntime { }); let guard = self.0.lock().unwrap(); with_extended_string(&mut key, &["/volumes/"], |key| { - for plugin in guard.plugins_manager.running_plugins() { + for plugin in guard.plugins_manager.started_plugins() { with_extended_string(key, &[plugin.name()], |key| { with_extended_string(key, &["/__path__"], |key| { if keyexpr::new(key.as_str()) diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index cfcd60a69f..d83a9d7824 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -26,7 +26,7 @@ use zenoh_util::LibLoader; pub enum PluginState { Declared, Loaded, - Running, + Started, } #[derive(Clone, Debug, PartialEq, Eq, Default)] @@ -92,12 +92,12 @@ pub trait DeclaredPlugin: PluginInfo { - fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin>; - fn running(&self) -> Option<&dyn RunningPlugin>; - fn running_mut(&mut self) -> Option<&mut dyn RunningPlugin>; + fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin>; + fn started(&self) -> Option<&dyn StartedPlugin>; + fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin>; } -pub trait RunningPlugin { +pub trait StartedPlugin : PluginInfo { fn stop(&mut self); fn instance(&self) -> &Instance; fn instance_mut(&mut self) -> &mut Instance; @@ -140,7 +140,7 @@ where state: self .instance .as_ref() - .map_or(PluginState::Loaded, |_| PluginState::Running), + .map_or(PluginState::Loaded, |_| PluginState::Started), condition: PluginCondition::new(), // TODO: request runnnig plugin status } } @@ -167,20 +167,20 @@ impl where P: Plugin, { - fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin> { + fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { if self.instance.is_none() { self.instance = Some(P::start(self.name(), args)?); } Ok(self) } - fn running(&self) -> Option<&dyn RunningPlugin> { + fn started(&self) -> Option<&dyn StartedPlugin> { if self.instance.is_some() { Some(self) } else { None } } - fn running_mut(&mut self) -> Option<&mut dyn RunningPlugin> { + fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin> { if self.instance.is_some() { Some(self) } else { @@ -190,7 +190,7 @@ where } impl - RunningPlugin for StaticPlugin + StartedPlugin for StaticPlugin where P: Plugin, { @@ -323,14 +323,14 @@ impl PluginInfo PluginStatus { state: if self.starter.is_some() { if self.instance.is_some() { - PluginState::Running + PluginState::Started } else { PluginState::Loaded } } else { PluginState::Declared }, - condition: self.condition.clone(), // TODO: request condition from running plugin + condition: self.condition.clone(), // TODO: request condition from started plugin } } } @@ -365,14 +365,14 @@ impl impl LoadedPlugin for DynamicPlugin { - fn run(&mut self, args: &StartArgs) -> ZResult<&mut dyn RunningPlugin> { + fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { let starter = self .starter .as_ref() .ok_or_else(|| format!("Plugin `{}` not loaded", self.name)) .add_error(&mut self.condition)?; - let already_running = self.instance.is_some(); - if !already_running { + let already_started = self.instance.is_some(); + if !already_started { let instance = starter .start(self.name(), args) .add_error(&mut self.condition)?; @@ -380,14 +380,14 @@ impl } Ok(self) } - fn running(&self) -> Option<&dyn RunningPlugin> { + fn started(&self) -> Option<&dyn StartedPlugin> { if self.instance.is_some() { Some(self) } else { None } } - fn running_mut(&mut self) -> Option<&mut dyn RunningPlugin> { + fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin> { if self.instance.is_some() { Some(self) } else { @@ -397,7 +397,7 @@ impl } impl - RunningPlugin for DynamicPlugin + StartedPlugin for DynamicPlugin { fn stop(&mut self) { self.instance = None; @@ -411,13 +411,13 @@ impl } struct PluginRecord( - Box>, + Box + Send>, ); impl PluginRecord { - fn new + 'static>(plugin: P) -> Self { + fn new + Send + 'static>(plugin: P) -> Self { Self(Box::new(plugin)) } } @@ -452,13 +452,13 @@ impl /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. -pub struct PluginsManager { +pub struct PluginsManager { default_lib_prefix: String, loader: Option, plugins: Vec>, } -impl +impl PluginsManager { /// Constructs a new plugin manager with dynamic library loading enabled. @@ -526,11 +526,6 @@ impl ZResult { - self.get_plugin_index(name) - .ok_or_else(|| format!("Plugin `{}` not found", name).into()) - } - /// Lists all plugins pub fn plugins(&self) -> impl Iterator> + '_ { self.plugins @@ -562,69 +557,66 @@ impl impl Iterator> + '_ { - self.loaded_plugins().filter_map(|p| p.running()) + ) -> impl Iterator> + '_ { + self.loaded_plugins().filter_map(|p| p.started()) } - /// Lists the running plugins mutable - pub fn running_plugins_mut( + /// Lists the started plugins mutable + pub fn started_plugins_mut( &mut self, - ) -> impl Iterator> + '_ { - self.loaded_plugins_mut().filter_map(|p| p.running_mut()) + ) -> impl Iterator> + '_ { + self.loaded_plugins_mut().filter_map(|p| p.started_mut()) } /// Returns single plugin record - pub fn plugin(&self, name: &str) -> ZResult<&dyn DeclaredPlugin> { - Ok(&self.plugins[self.get_plugin_index_err(name)?]) + pub fn plugin(&self, name: &str) -> Option<&dyn DeclaredPlugin> { + let index = self.get_plugin_index(name)?; + Some(&self.plugins[index]) } /// Returns mutable plugin record pub fn plugin_mut( &mut self, name: &str, - ) -> ZResult<&mut dyn DeclaredPlugin> { - let index = self.get_plugin_index_err(name)?; - Ok(&mut self.plugins[index]) + ) -> Option<&mut dyn DeclaredPlugin> { + let index = self.get_plugin_index(name)?; + Some(&mut self.plugins[index]) } /// Returns loaded plugin record - pub fn loaded_plugin(&self, name: &str) -> ZResult<&dyn LoadedPlugin> { - Ok(self + pub fn loaded_plugin(&self, name: &str) -> Option<&dyn LoadedPlugin> { + self .plugin(name)? .loaded() - .ok_or_else(|| format!("Plugin `{}` not loaded", name))?) } /// Returns mutable loaded plugin record pub fn loaded_plugin_mut( &mut self, name: &str, - ) -> ZResult<&mut dyn LoadedPlugin> { - Ok(self + ) -> Option<&mut dyn LoadedPlugin> { + self .plugin_mut(name)? .loaded_mut() - .ok_or_else(|| format!("Plugin `{}` not loaded", name))?) } - /// Returns running plugin record - pub fn running_plugin(&self, name: &str) -> ZResult<&dyn RunningPlugin> { - Ok(self + /// Returns started plugin record + pub fn started_plugin(&self, name: &str) -> Option<&dyn StartedPlugin> { + self .loaded_plugin(name)? - .running() - .ok_or_else(|| format!("Plugin `{}` is not running", name))?) + .started() } - /// Returns mutable running plugin record - pub fn running_plugin_mut( + /// Returns mutable started plugin record + pub fn started_plugin_mut( &mut self, name: &str, - ) -> ZResult<&mut dyn RunningPlugin> { - Ok(self + ) -> Option<&mut dyn StartedPlugin> { + self .loaded_plugin_mut(name)? - .running_mut() - .ok_or_else(|| format!("Plugin `{}` is not running", name))?) + .started_mut() } } diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index d9fa052709..6cf16feebd 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -1,4 +1,3 @@ -use std::fmt::Display; // // Copyright (c) 2023 ZettaScale Technology @@ -16,19 +15,20 @@ use std::fmt::Display; use crate::*; pub use no_mangle::*; use zenoh_result::ZResult; +use std::fmt::Display; pub type PluginLoaderVersion = u64; pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; pub const FEATURES: &str = concat_enabled_features!(prefix = "zenoh-plugin-trait", features = ["default"]); -type StartFn = fn(&str, &StartArgs) -> ZResult; +type StartFn = fn(&str, &StartArgs) -> ZResult; #[repr(C)] -pub struct PluginVTable { - pub start: StartFn, +pub struct PluginVTable { + pub start: StartFn, } -impl CompatibilityVersion for PluginVTable { +impl CompatibilityVersion for PluginVTable { fn version() -> u64 { 1 } @@ -71,27 +71,27 @@ pub struct Compatibility { rust_version: RustVersion, vtable_version: StructVersion, start_args_version: StructVersion, - running_plugin_version: StructVersion, + instance_version: StructVersion, } impl Compatibility { - pub fn new() -> Self { + pub fn new() -> Self { let rust_version = RustVersion::new(); - let vtable_version = StructVersion::new::>(); + let vtable_version = StructVersion::new::>(); let start_args_version = StructVersion::new::(); - let running_plugin_version = StructVersion::new::(); + let instance_version = StructVersion::new::(); Self { rust_version, vtable_version, start_args_version, - running_plugin_version, + instance_version, } } pub fn are_compatible(&self, other: &Self) -> bool { RustVersion::are_compatible(&self.rust_version, &other.rust_version) && self.vtable_version == other.vtable_version && self.start_args_version == other.start_args_version - && self.running_plugin_version == other.running_plugin_version + && self.instance_version == other.instance_version } } @@ -99,11 +99,11 @@ impl Display for Compatibility { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "{}\nVTable:{}StartArgs:{}RunningPlugin:{}", + "{}\nVTable:{}StartArgs:{}Instance:{}", self.rust_version, self.vtable_version, self.start_args_version, - self.running_plugin_version + self.instance_version ) } } @@ -165,8 +165,8 @@ impl Default for RustVersion { } } -impl PluginVTable { - pub fn new>() -> Self { +impl PluginVTable { + pub fn new>() -> Self { Self { start: ConcretePlugin::start, } @@ -190,14 +190,14 @@ pub mod no_mangle { // TODO: add vtable version (including type parameters) to the compatibility information $crate::prelude::Compatibility::new::< <$ty as $crate::prelude::Plugin>::StartArgs, - <$ty as $crate::prelude::Plugin>::RunningPlugin, + <$ty as $crate::prelude::Plugin>::Instance, >() } #[no_mangle] fn load_plugin() -> $crate::prelude::PluginVTable< <$ty as $crate::prelude::Plugin>::StartArgs, - <$ty as $crate::prelude::Plugin>::RunningPlugin, + <$ty as $crate::prelude::Plugin>::Instance, > { $crate::prelude::PluginVTable::new::<$ty>() } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 5e0df31a77..fb937e3bb8 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -73,12 +73,55 @@ impl ConfigValidator for AdminSpace { new: &serde_json::Map, ) -> ZResult>> { let plugins_mgr = zlock!(self.context.plugins_mgr); - let plugin = plugins_mgr.running_plugin(name)?; + let plugin = plugins_mgr.started_plugin(name).ok_or(format!( + "Plugin `{}` is not running, but its configuration is being changed", + name + ))?; plugin.instance().config_checker(path, current, new) } } impl AdminSpace { + fn start_plugin( + plugin_mgr: &mut plugins::PluginsManager, + config: &crate::config::PluginLoad, + start_args: &Runtime, + ) -> ZResult<()> { + let name = &config.name; + let declared = if let Some(declared) = plugin_mgr.plugin_mut(name) { + log::warn!("Plugin `{}` was already declared", declared.name()); + declared + } else if let Some(paths) = &config.paths { + plugin_mgr.add_dynamic_plugin_by_paths(name, paths)? + } else { + plugin_mgr.add_dynamic_plugin_by_name(name, name)? + }; + + let loaded = if let Some(loaded) = declared.loaded_mut() { + log::warn!( + "Plugin `{}` was already loaded from {}", + loaded.name(), + loaded.path() + ); + loaded + } else { + declared.load()? + }; + + if let Some(started) = loaded.started_mut() { + log::warn!("Plugin `{}` was already started", started.name()); + } else { + let started = loaded.start(start_args)?; + log::info!( + "Successfully started plugin `{}` from {}", + started.name(), + started.path() + ); + }; + + Ok(()) + } + pub async fn start(runtime: &Runtime, plugins_mgr: plugins::PluginsManager, version: String) { let zid_str = runtime.state.zid.to_string(); let metadata = runtime.state.metadata.clone(); @@ -122,7 +165,7 @@ impl AdminSpace { ); let mut active_plugins = plugins_mgr - .running_plugins() + .started_plugins() .map(|rec| (rec.name().to_string(), rec.path().to_string())) .collect::>(); @@ -188,67 +231,31 @@ impl AdminSpace { match diff { PluginDiff::Delete(name) => { active_plugins.remove(name.as_str()); - if let Ok(running) = plugins_mgr.running_plugin_mut(&name) { + if let Some(running) = plugins_mgr.started_plugin_mut(&name) { running.stop() } } PluginDiff::Start(plugin) => { - let name = &plugin.name; - let rec = if let Some(paths) = &plugin.paths { - plugins_mgr.load_plugin_by_paths(name, paths) - } else { - plugins_mgr.load_plugin_by_backend_name(name, &plugin.name) - }; - match rec { - Ok((loaded, rec)) => { - if loaded { - log::info!( - "Loaded plugin `{}` from {}", - rec.name(), - rec.path() - ); - } else { - log::warn!( - "Plugin `{}` was already loaded from {}", - rec.name(), - rec.path() - ); - } - match rec.run(&admin.context.runtime) { - Ok((true, rec)) => { - active_plugins - .insert(name.into(), rec.path().to_string()); - log::info!( - "Successfully started plugin `{}` from {}", - rec.name(), - rec.path() - ); - } - Ok((false, _)) => { - log::warn!("Plugin `{}` was already running", name) - } - Err(e) => { - log::error!( - "Failed to start plugin `{}`: {}", - name, - e - ) - } - } - } - Err(e) => { - if plugin.required { - panic!("Failed to load plugin `{}`: {}", name, e) - } else { - log::error!("Failed to load plugin `{}`: {}", name, e) - } + if let Err(e) = Self::start_plugin( + &mut plugins_mgr, + &plugin, + &admin.context.runtime, + ) { + if plugin.required { + panic!("Failed to load plugin `{}`: {}", plugin.name, e) + } else { + log::error!( + "Failed to load plugin `{}`: {}", + plugin.name, + e + ) } } } } } - log::info!("Running plugins: {:?}", &active_plugins) } + log::info!("Running plugins: {:?}", &active_plugins) } }); @@ -443,7 +450,7 @@ fn router_data(context: &AdminContext, query: Query) { let plugins: serde_json::Value = { let plugins_mgr = zlock!(context.plugins_mgr); plugins_mgr - .running_plugins() + .started_plugins() .map(|rec| (rec.name(), json!({ "path": rec.path() }))) .collect() }; @@ -648,7 +655,7 @@ fn plugins_status(context: &AdminContext, query: Query) { let guard = zlock!(context.plugins_mgr); let mut root_key = format!("@/router/{}/status/plugins/", &context.zid_str); - for plugin in guard.running_plugins() { + for plugin in guard.started_plugins() { with_extended_string(&mut root_key, &[plugin.name()], |plugin_key| { with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { if let Ok(key_expr) = KeyExpr::try_from(plugin_path_key.clone()) { diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index fe9b6a473d..3bd126ef69 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -15,6 +15,7 @@ use async_std::task; use clap::{ArgMatches, Command}; use futures::future; use git_version::git_version; +use zenoh::Result; use std::collections::HashSet; use zenoh::config::{Config, ModeDependentValue, PermissionsConf, PluginLoad, ValidatedMap}; use zenoh::plugins::PluginsManager; @@ -29,6 +30,32 @@ lazy_static::lazy_static!( const DEFAULT_LISTENER: &str = "tcp/[::]:7447"; +fn load_plugin( + plugin_mgr: &mut PluginsManager, + name: &str, + paths: &Option>, +) -> Result<()> { + let declared = if let Some(declared) = plugin_mgr.plugin_mut(name) { + log::warn!("Plugin `{}` was already declared", declared.name()); + declared + } else if let Some(paths) = paths { + plugin_mgr.add_dynamic_plugin_by_paths(name, paths)? + } else { + plugin_mgr.add_dynamic_plugin_by_name(name, name)? + }; + + if let Some(loaded) = declared.loaded_mut() { + log::warn!( + "Plugin `{}` was already loaded from {}", + loaded.name(), + loaded.path() + ); + } else { + let _ = declared.load()?; + }; + Ok(()) +} + fn main() { task::block_on(async { let mut log_builder = @@ -89,10 +116,7 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na "Loading {req} plugin \"{name}\"", req = if required { "required" } else { "" } ); - if let Err(e) = match paths { - None => plugin_mgr.load_plugin_by_backend_name(&name, &name), - Some(paths) => plugin_mgr.load_plugin_by_paths(name.clone(), &paths), - } { + if let Err(e) = load_plugin(&mut plugin_mgr, &name, &paths) { if required { panic!("Plugin load failure: {}", e) } else { @@ -112,14 +136,14 @@ clap::Arg::new("adminspace-permissions").long("adminspace-permissions").value_na } }; - for plugin in plugin_mgr.plugins_mut() { + for plugin in plugin_mgr.loaded_plugins_mut() { let required = required_plugins.contains(plugin.name()); log::info!( "Starting {req} plugin \"{name}\"", req = if required { "required" } else { "" }, name = plugin.name() ); - match plugin.run(&runtime) { + match plugin.start(&runtime) { Ok(_) => { log::info!( "Successfully started plugin {} from {:?}", From ef81a46e810cf55f018f61394b2a35bdd3509af9 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 8 Nov 2023 18:27:53 +0100 Subject: [PATCH 038/106] memory plugin loading fix --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 9a0c88121b..6c4179f32f 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -164,7 +164,9 @@ impl StorageRuntimeInner { fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); - let declared = if let Some(paths) = config.paths() { + let declared = if let Some(declared) = self.plugins_manager.plugin_mut(volume_id) { + declared + } else if let Some(paths) = config.paths() { self.plugins_manager.add_dynamic_plugin_by_paths(volume_id, paths)? } else { self.plugins_manager From 1d136dcbf48dbebfe35a0aa90a66a881586b3a59 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 8 Nov 2023 19:16:08 +0100 Subject: [PATCH 039/106] startargs and instance traits --- plugins/zenoh-backend-traits/src/config.rs | 4 +- plugins/zenoh-backend-traits/src/lib.rs | 10 ++- plugins/zenoh-plugin-trait/src/lib.rs | 7 ++- plugins/zenoh-plugin-trait/src/loading.rs | 71 +++++++++------------- zenoh/src/net/runtime/mod.rs | 4 +- zenoh/src/plugins/sealed.rs | 10 +++ 6 files changed, 60 insertions(+), 46 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index 8587993a7c..e268f1f5c4 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -18,7 +18,7 @@ use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; -use zenoh_plugin_trait::CompatibilityVersion; +use zenoh_plugin_trait::{CompatibilityVersion, PluginStartArgs}; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] @@ -78,6 +78,8 @@ impl CompatibilityVersion for VolumeConfig { } } +impl PluginStartArgs for VolumeConfig {} + impl Default for ReplicaConfig { fn default() -> Self { Self { diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index bd4730119f..42d95d6cb4 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -139,7 +139,7 @@ use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; -use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion}; +use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion, PluginControl, PluginInstance}; pub mod config; use config::{StorageConfig, VolumeConfig}; @@ -232,6 +232,14 @@ impl CompatibilityVersion for VolumePlugin { } } +impl PluginControl for VolumePlugin { + fn plugins(&self) -> Vec<&str> { + Vec::new() + } +} + +impl PluginInstance for VolumePlugin {} + /// Trait to be implemented by a Storage. #[async_trait] pub trait Storage: Send + Sync { diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 8aa9ad0b53..22c50970b7 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -54,9 +54,12 @@ pub trait PluginControl { // fn status(&self, name: &str) -> PluginStatus; } +pub trait PluginStartArgs : CompatibilityVersion {} +pub trait PluginInstance : CompatibilityVersion + PluginControl + Send {} + pub trait Plugin: Sized + 'static { - type StartArgs: CompatibilityVersion; - type Instance: CompatibilityVersion; + type StartArgs: PluginStartArgs; + type Instance: PluginInstance; /// Your plugins' default name when statically linked. const STATIC_NAME: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index d83a9d7824..bcf531bee3 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -82,28 +82,24 @@ pub trait PluginInfo { fn status(&self) -> PluginStatus; } -pub trait DeclaredPlugin: - PluginInfo -{ +pub trait DeclaredPlugin: PluginInfo { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin>; fn loaded(&self) -> Option<&dyn LoadedPlugin>; fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin>; } -pub trait LoadedPlugin: - PluginInfo -{ +pub trait LoadedPlugin: PluginInfo { fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin>; fn started(&self) -> Option<&dyn StartedPlugin>; fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin>; } -pub trait StartedPlugin : PluginInfo { +pub trait StartedPlugin: PluginInfo { fn stop(&mut self); fn instance(&self) -> &Instance; fn instance_mut(&mut self) -> &mut Instance; } -struct StaticPlugin +struct StaticPlugin where P: Plugin, { @@ -111,8 +107,7 @@ where phantom: PhantomData

, } -impl - StaticPlugin +impl StaticPlugin where P: Plugin, { @@ -124,7 +119,7 @@ where } } -impl PluginInfo +impl PluginInfo for StaticPlugin where P: Plugin, @@ -146,7 +141,7 @@ where } } -impl +impl DeclaredPlugin for StaticPlugin where P: Plugin, @@ -162,7 +157,7 @@ where } } -impl +impl LoadedPlugin for StaticPlugin where P: Plugin, @@ -189,7 +184,7 @@ where } } -impl +impl StartedPlugin for StaticPlugin where P: Plugin, @@ -231,13 +226,13 @@ impl DynamicPluginSource { } } -struct DynamicPluginStarter { +struct DynamicPluginStarter { _lib: Library, path: PathBuf, vtable: PluginVTable, } -impl +impl DynamicPluginStarter { fn get_vtable(lib: &Library, path: &Path) -> ZResult> { @@ -288,7 +283,7 @@ impl } } -struct DynamicPlugin { +struct DynamicPlugin { name: String, condition: PluginCondition, source: DynamicPluginSource, @@ -296,7 +291,7 @@ struct DynamicPlugin, } -impl +impl DynamicPlugin { fn new(name: String, source: DynamicPluginSource) -> Self { @@ -310,7 +305,7 @@ impl } } -impl PluginInfo +impl PluginInfo for DynamicPlugin { fn name(&self) -> &str { @@ -335,7 +330,7 @@ impl PluginInfo } } -impl +impl DeclaredPlugin for DynamicPlugin { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { @@ -362,7 +357,7 @@ impl } } -impl +impl LoadedPlugin for DynamicPlugin { fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { @@ -396,7 +391,7 @@ impl } } -impl +impl StartedPlugin for DynamicPlugin { fn stop(&mut self) { @@ -410,11 +405,11 @@ impl } } -struct PluginRecord( +struct PluginRecord( Box + Send>, ); -impl +impl PluginRecord { fn new + Send + 'static>(plugin: P) -> Self { @@ -422,7 +417,7 @@ impl } } -impl PluginInfo +impl PluginInfo for PluginRecord { fn name(&self) -> &str { @@ -436,7 +431,7 @@ impl PluginInfo } } -impl +impl DeclaredPlugin for PluginRecord { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { @@ -452,14 +447,16 @@ impl /// A plugins manager that handles starting and stopping plugins. /// Plugins can be loaded from shared libraries using [`Self::load_plugin_by_name`] or [`Self::load_plugin_by_paths`], or added directly from the binary if available using [`Self::add_static`]. -pub struct PluginsManager { +pub struct PluginsManager { default_lib_prefix: String, loader: Option, plugins: Vec>, } -impl - PluginsManager +impl< + StartArgs: PluginStartArgs + 'static, + Instance: PluginInstance + 'static, + > PluginsManager { /// Constructs a new plugin manager with dynamic library loading enabled. pub fn dynamic>(loader: LibLoader, default_lib_prefix: S) -> Self { @@ -588,9 +585,7 @@ impl Option<&dyn LoadedPlugin> { - self - .plugin(name)? - .loaded() + self.plugin(name)?.loaded() } /// Returns mutable loaded plugin record @@ -598,16 +593,12 @@ impl Option<&mut dyn LoadedPlugin> { - self - .plugin_mut(name)? - .loaded_mut() + self.plugin_mut(name)?.loaded_mut() } /// Returns started plugin record pub fn started_plugin(&self, name: &str) -> Option<&dyn StartedPlugin> { - self - .loaded_plugin(name)? - .started() + self.loaded_plugin(name)?.started() } /// Returns mutable started plugin record @@ -615,8 +606,6 @@ impl Option<&mut dyn StartedPlugin> { - self - .loaded_plugin_mut(name)? - .started_mut() + self.loaded_plugin_mut(name)?.started_mut() } } diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index ef9db31862..1347efdd57 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -37,7 +37,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::CompatibilityVersion; +use zenoh_plugin_trait::{CompatibilityVersion, PluginStartArgs}; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; @@ -74,6 +74,8 @@ impl CompatibilityVersion for Runtime { } } +impl PluginStartArgs for Runtime {} + impl Runtime { pub async fn new(config: Config) -> ZResult { let mut runtime = Runtime::init(config).await?; diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 7eacbc0077..f25337544f 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -40,6 +40,14 @@ impl CompatibilityVersion for RunningPlugin { } } +impl PluginControl for RunningPlugin { + fn plugins(&self) -> Vec<&str> { + Vec::new() + } +} + +impl PluginInstance for RunningPlugin {} + #[non_exhaustive] #[derive(serde::Serialize, Debug, Clone)] /// A Response for the administration space. @@ -86,3 +94,5 @@ pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager Date: Fri, 10 Nov 2023 12:46:08 +0100 Subject: [PATCH 040/106] plruings method cow --- plugins/zenoh-backend-traits/src/lib.rs | 3 ++- plugins/zenoh-plugin-trait/src/lib.rs | 4 +++- plugins/zenoh-plugin-trait/src/loading.rs | 11 +++++++++-- zenoh/src/plugins/sealed.rs | 4 +++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 42d95d6cb4..4669f1eadd 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -133,6 +133,7 @@ use async_trait::async_trait; use const_format::concatcp; +use std::borrow::Cow; use std::sync::Arc; use zenoh::prelude::{KeyExpr, OwnedKeyExpr, Sample, Selector}; use zenoh::queryable::ReplyBuilder; @@ -233,7 +234,7 @@ impl CompatibilityVersion for VolumePlugin { } impl PluginControl for VolumePlugin { - fn plugins(&self) -> Vec<&str> { + fn plugins(&self) -> Vec> { Vec::new() } } diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 22c50970b7..3ce73ea116 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -21,6 +21,8 @@ pub mod loading; pub mod vtable; +use std::borrow::Cow; + use zenoh_result::ZResult; pub mod prelude { @@ -50,7 +52,7 @@ pub trait CompatibilityVersion { } pub trait PluginControl { - fn plugins(&self) -> Vec<&str>; + fn plugins(&self) -> Vec>; // fn status(&self, name: &str) -> PluginStatus; } diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index bcf531bee3..ff170d0446 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -57,17 +57,24 @@ impl PluginCondition { } } -pub trait PluginConditionAddError { +pub trait PluginConditionSetter { fn add_error(self, condition: &mut PluginCondition) -> Self; + fn add_warning(self, condition: &mut PluginCondition) -> Self; } -impl PluginConditionAddError for core::result::Result { +impl PluginConditionSetter for core::result::Result { fn add_error(self, condition: &mut PluginCondition) -> Self { if let Err(e) = &self { condition.add_error(e.to_string()); } self } + fn add_warning(self, condition: &mut PluginCondition) -> Self { + if let Err(e) = &self { + condition.add_warning(e.to_string()); + } + self + } } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index f25337544f..14c658a99c 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -14,6 +14,8 @@ //! `zenohd`'s plugin system. For more details, consult the [detailed documentation](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Plugins/Zenoh%20Plugins.md). +use std::borrow::Cow; + use crate::prelude::Selector; pub use crate::runtime::Runtime; pub use crate::Result as ZResult; @@ -41,7 +43,7 @@ impl CompatibilityVersion for RunningPlugin { } impl PluginControl for RunningPlugin { - fn plugins(&self) -> Vec<&str> { + fn plugins(&self) -> Vec> { Vec::new() } } From 85193fb7a83f1b5d2cf853ed63d5bc41713d0aa8 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 10 Nov 2023 14:41:43 +0100 Subject: [PATCH 041/106] plugin trait sources reorganised --- plugins/zenoh-backend-traits/src/config.rs | 4 +- plugins/zenoh-backend-traits/src/lib.rs | 4 +- .../zenoh-plugin-storage-manager/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/src/lib.rs | 47 +- plugins/zenoh-plugin-trait/src/loading.rs | 400 +----------------- .../src/loading/dynamic_plugin.rs | 225 ++++++++++ .../src/loading/static_plugin.rs | 114 +++++ plugins/zenoh-plugin-trait/src/plugin.rs | 110 +++++ plugins/zenoh-plugin-trait/src/vtable.rs | 32 +- zenoh/src/net/runtime/mod.rs | 4 +- zenoh/src/plugins/sealed.rs | 6 +- 11 files changed, 495 insertions(+), 453 deletions(-) create mode 100644 plugins/zenoh-plugin-trait/src/loading/dynamic_plugin.rs create mode 100644 plugins/zenoh-plugin-trait/src/loading/static_plugin.rs create mode 100644 plugins/zenoh-plugin-trait/src/plugin.rs diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index e268f1f5c4..976b1e4846 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -18,7 +18,7 @@ use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; -use zenoh_plugin_trait::{CompatibilityVersion, PluginStartArgs}; +use zenoh_plugin_trait::{PluginStructVersion, PluginStartArgs}; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] @@ -69,7 +69,7 @@ pub struct ReplicaConfig { pub delta: Duration, } -impl CompatibilityVersion for VolumeConfig { +impl PluginStructVersion for VolumeConfig { fn version() -> u64 { 1 } diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 4669f1eadd..03ad09253c 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -140,7 +140,7 @@ use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; -use zenoh_plugin_trait::{concat_enabled_features, CompatibilityVersion, PluginControl, PluginInstance}; +use zenoh_plugin_trait::{concat_enabled_features, PluginStructVersion, PluginControl, PluginInstance}; pub mod config; use config::{StorageConfig, VolumeConfig}; @@ -224,7 +224,7 @@ pub trait Volume: Send + Sync { pub type VolumePlugin = Box; -impl CompatibilityVersion for VolumePlugin { +impl PluginStructVersion for VolumePlugin { fn version() -> u64 { 1 } diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 6c4179f32f..7d1d762a16 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -72,7 +72,7 @@ impl Plugin for StoragesPlugin { } } -type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; +type PluginsManager = zenoh_plugin_trait::PluginsManager; struct StorageRuntime(Arc>); struct StorageRuntimeInner { diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 3ce73ea116..6c6be740d1 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -18,16 +18,17 @@ //! //! If building a plugin for [`zenohd`](https://crates.io/crates/zenoh), you should use the types exported in [`zenoh::plugins`](https://docs.rs/zenoh/latest/zenoh/plugins) to fill [`Plugin`]'s associated types. //! To check your plugin typing for `zenohd`, have your plugin implement [`zenoh::plugins::ZenohPlugin`](https://docs.rs/zenoh/latest/zenoh/plugins/struct.ZenohPlugin) -pub mod loading; -pub mod vtable; - -use std::borrow::Cow; +//! +mod loading; +mod plugin; +mod vtable; -use zenoh_result::ZResult; - -pub mod prelude { - pub use crate::{concat_enabled_features, loading::*, vtable::*, CompatibilityVersion, Plugin}; -} +pub use loading::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; +pub use plugin::{ + Plugin, PluginCondition, PluginConditionSetter, PluginControl, PluginInfo, PluginInstance, + PluginStartArgs, PluginState, PluginStatus, PluginStructVersion, +}; +pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; #[macro_export] macro_rules! concat_enabled_features { @@ -41,29 +42,5 @@ macro_rules! concat_enabled_features { }; } -pub trait CompatibilityVersion { - /// The version of the structure implementing this trait. After any channge in the structure or it's dependencies - /// whcich may affect the ABI, this version should be incremented. - fn version() -> u64; - /// The features enabled during comiplation of the structure implementing this trait. - /// Different features between the plugin and the host may cuase ABI incompatibility even if the structure version is the same. - /// Use `concat_enabled_features!` to generate this string - fn features() -> &'static str; -} - -pub trait PluginControl { - fn plugins(&self) -> Vec>; - // fn status(&self, name: &str) -> PluginStatus; -} - -pub trait PluginStartArgs : CompatibilityVersion {} -pub trait PluginInstance : CompatibilityVersion + PluginControl + Send {} - -pub trait Plugin: Sized + 'static { - type StartArgs: PluginStartArgs; - type Instance: PluginInstance; - /// Your plugins' default name when statically linked. - const STATIC_NAME: &'static str; - /// Starts your plugin. Use `Ok` to return your plugin's control structure - fn start(name: &str, args: &Self::StartArgs) -> ZResult; -} +pub const FEATURES: &str = + concat_enabled_features!(prefix = "zenoh-plugin-trait", features = ["default"]); diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index ff170d0446..81b744807c 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -1,4 +1,3 @@ -// // Copyright (c) 2023 ZettaScale Technology // // This program and the accompanying materials are made available under the @@ -11,83 +10,14 @@ // Contributors: // ZettaScale Zenoh Team, // +mod static_plugin; +mod dynamic_plugin; + use crate::*; -use libloading::Library; -use std::{ - borrow::Cow, - marker::PhantomData, - path::{Path, PathBuf}, -}; -use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; -use zenoh_result::{bail, ZResult}; +use zenoh_result::ZResult; use zenoh_util::LibLoader; -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum PluginState { - Declared, - Loaded, - Started, -} - -#[derive(Clone, Debug, PartialEq, Eq, Default)] -pub struct PluginCondition { - warnings: Vec>, - errors: Vec>, -} - -impl PluginCondition { - pub fn new() -> Self { - Self::default() - } - pub fn clear(&mut self) { - self.warnings.clear(); - self.errors.clear(); - } - pub fn add_error>>(&mut self, error: S) { - self.errors.push(error.into()); - } - pub fn add_warning>>(&mut self, warning: S) { - self.warnings.push(warning.into()); - } - pub fn errors(&self) -> &[Cow<'static, str>] { - &self.errors - } - pub fn warnings(&self) -> &[Cow<'static, str>] { - &self.warnings - } -} - -pub trait PluginConditionSetter { - fn add_error(self, condition: &mut PluginCondition) -> Self; - fn add_warning(self, condition: &mut PluginCondition) -> Self; -} - -impl PluginConditionSetter for core::result::Result { - fn add_error(self, condition: &mut PluginCondition) -> Self { - if let Err(e) = &self { - condition.add_error(e.to_string()); - } - self - } - fn add_warning(self, condition: &mut PluginCondition) -> Self { - if let Err(e) = &self { - condition.add_warning(e.to_string()); - } - self - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct PluginStatus { - pub state: PluginState, - pub condition: PluginCondition, -} - -pub trait PluginInfo { - fn name(&self) -> &str; - fn path(&self) -> &str; - fn status(&self) -> PluginStatus; -} +use self::{dynamic_plugin::{DynamicPlugin, DynamicPluginSource}, static_plugin::StaticPlugin}; pub trait DeclaredPlugin: PluginInfo { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin>; @@ -106,319 +36,11 @@ pub trait StartedPlugin: PluginInfo { fn instance_mut(&mut self) -> &mut Instance; } -struct StaticPlugin -where - P: Plugin, -{ - instance: Option, - phantom: PhantomData

, -} - -impl StaticPlugin -where - P: Plugin, -{ - fn new() -> Self { - Self { - instance: None, - phantom: PhantomData, - } - } -} - -impl PluginInfo - for StaticPlugin -where - P: Plugin, -{ - fn name(&self) -> &str { - P::STATIC_NAME - } - fn path(&self) -> &str { - "" - } - fn status(&self) -> PluginStatus { - PluginStatus { - state: self - .instance - .as_ref() - .map_or(PluginState::Loaded, |_| PluginState::Started), - condition: PluginCondition::new(), // TODO: request runnnig plugin status - } - } -} - -impl - DeclaredPlugin for StaticPlugin -where - P: Plugin, -{ - fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { - Ok(self) - } - fn loaded(&self) -> Option<&dyn LoadedPlugin> { - Some(self) - } - fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { - Some(self) - } -} - -impl - LoadedPlugin for StaticPlugin -where - P: Plugin, -{ - fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { - if self.instance.is_none() { - self.instance = Some(P::start(self.name(), args)?); - } - Ok(self) - } - fn started(&self) -> Option<&dyn StartedPlugin> { - if self.instance.is_some() { - Some(self) - } else { - None - } - } - fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin> { - if self.instance.is_some() { - Some(self) - } else { - None - } - } -} - -impl - StartedPlugin for StaticPlugin -where - P: Plugin, -{ - fn stop(&mut self) {} - fn instance(&self) -> &Instance { - self.instance.as_ref().unwrap() - } - fn instance_mut(&mut self) -> &mut Instance { - self.instance.as_mut().unwrap() - } -} - -/// This enum contains information where to load the plugin from. -enum DynamicPluginSource { - /// Load plugin with the name in String + `.so | .dll | .dylib` - /// in LibLoader's search paths. - ByName((LibLoader, String)), - /// Load first avalilable plugin from the list of path to plugin files (absolute or relative to the current working directory) - ByPaths(Vec), -} - -impl DynamicPluginSource { - fn load(&self) -> ZResult<(Library, PathBuf)> { - match self { - DynamicPluginSource::ByName((libloader, name)) => unsafe { - libloader.search_and_load(name) - }, - DynamicPluginSource::ByPaths(paths) => { - for path in paths { - match unsafe { LibLoader::load_file(path) } { - Ok((l, p)) => return Ok((l, p)), - Err(e) => log::warn!("Plugin {} load fail: {}", path, e), - } - } - bail!("Plugin not found in {:?}", &paths) - } - } - } -} - -struct DynamicPluginStarter { - _lib: Library, - path: PathBuf, - vtable: PluginVTable, -} - -impl - DynamicPluginStarter -{ - fn get_vtable(lib: &Library, path: &Path) -> ZResult> { - log::debug!("Loading plugin {}", &path.to_str().unwrap(),); - let get_plugin_loader_version = - unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; - let plugin_loader_version = get_plugin_loader_version(); - log::debug!("Plugin loader version: {}", &plugin_loader_version); - if plugin_loader_version != PLUGIN_LOADER_VERSION { - bail!( - "Plugin loader version mismatch: host = {}, plugin = {}", - PLUGIN_LOADER_VERSION, - plugin_loader_version - ); - } - let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; - let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = Compatibility::new::(); - log::debug!( - "Plugin compativilty record: {:?}", - &plugin_compatibility_record - ); - if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { - bail!( - "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", - host_compatibility_record, - plugin_compatibility_record - ); - } - let load_plugin = - unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; - let vtable = load_plugin(); - Ok(vtable) - } - fn new(lib: Library, path: PathBuf) -> ZResult { - let vtable = Self::get_vtable(&lib, &path)?; - Ok(Self { - _lib: lib, - path, - vtable, - }) - } - fn start(&self, name: &str, args: &StartArgs) -> ZResult { - (self.vtable.start)(name, args) - } - fn path(&self) -> &str { - self.path.to_str().unwrap() - } -} - -struct DynamicPlugin { - name: String, - condition: PluginCondition, - source: DynamicPluginSource, - starter: Option>, - instance: Option, -} - -impl - DynamicPlugin -{ - fn new(name: String, source: DynamicPluginSource) -> Self { - Self { - name, - condition: PluginCondition::new(), - source, - starter: None, - instance: None, - } - } -} - -impl PluginInfo - for DynamicPlugin -{ - fn name(&self) -> &str { - self.name.as_str() - } - fn path(&self) -> &str { - self.starter.as_ref().map_or("", |v| v.path()) - } - fn status(&self) -> PluginStatus { - PluginStatus { - state: if self.starter.is_some() { - if self.instance.is_some() { - PluginState::Started - } else { - PluginState::Loaded - } - } else { - PluginState::Declared - }, - condition: self.condition.clone(), // TODO: request condition from started plugin - } - } -} - -impl - DeclaredPlugin for DynamicPlugin -{ - fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { - if self.starter.is_none() { - let (lib, path) = self.source.load().add_error(&mut self.condition)?; - let starter = DynamicPluginStarter::new(lib, path).add_error(&mut self.condition)?; - self.starter = Some(starter); - } - Ok(self) - } - fn loaded(&self) -> Option<&dyn LoadedPlugin> { - if self.starter.is_some() { - Some(self) - } else { - None - } - } - fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { - if self.starter.is_some() { - Some(self) - } else { - None - } - } -} - -impl - LoadedPlugin for DynamicPlugin -{ - fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { - let starter = self - .starter - .as_ref() - .ok_or_else(|| format!("Plugin `{}` not loaded", self.name)) - .add_error(&mut self.condition)?; - let already_started = self.instance.is_some(); - if !already_started { - let instance = starter - .start(self.name(), args) - .add_error(&mut self.condition)?; - self.instance = Some(instance); - } - Ok(self) - } - fn started(&self) -> Option<&dyn StartedPlugin> { - if self.instance.is_some() { - Some(self) - } else { - None - } - } - fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin> { - if self.instance.is_some() { - Some(self) - } else { - None - } - } -} - -impl - StartedPlugin for DynamicPlugin -{ - fn stop(&mut self) { - self.instance = None; - } - fn instance(&self) -> &Instance { - self.instance.as_ref().unwrap() - } - fn instance_mut(&mut self) -> &mut Instance { - self.instance.as_mut().unwrap() - } -} - struct PluginRecord( Box + Send>, ); -impl - PluginRecord -{ +impl PluginRecord { fn new + Send + 'static>(plugin: P) -> Self { Self(Box::new(plugin)) } @@ -438,8 +60,8 @@ impl PluginInfo } } -impl - DeclaredPlugin for PluginRecord +impl DeclaredPlugin + for PluginRecord { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { self.0.load() @@ -460,10 +82,8 @@ pub struct PluginsManager plugins: Vec>, } -impl< - StartArgs: PluginStartArgs + 'static, - Instance: PluginInstance + 'static, - > PluginsManager +impl + PluginsManager { /// Constructs a new plugin manager with dynamic library loading enabled. pub fn dynamic>(loader: LibLoader, default_lib_prefix: S) -> Self { diff --git a/plugins/zenoh-plugin-trait/src/loading/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/loading/dynamic_plugin.rs new file mode 100644 index 0000000000..898016e1be --- /dev/null +++ b/plugins/zenoh-plugin-trait/src/loading/dynamic_plugin.rs @@ -0,0 +1,225 @@ +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::*; +use std::path::{PathBuf, Path}; + +use libloading::Library; +use zenoh_result::{ZResult, bail}; +use zenoh_util::LibLoader; + + +/// This enum contains information where to load the plugin from. +pub enum DynamicPluginSource { + /// Load plugin with the name in String + `.so | .dll | .dylib` + /// in LibLoader's search paths. + ByName((LibLoader, String)), + /// Load first avalilable plugin from the list of path to plugin files (absolute or relative to the current working directory) + ByPaths(Vec), +} + +impl DynamicPluginSource { + fn load(&self) -> ZResult<(Library, PathBuf)> { + match self { + DynamicPluginSource::ByName((libloader, name)) => unsafe { + libloader.search_and_load(name) + }, + DynamicPluginSource::ByPaths(paths) => { + for path in paths { + match unsafe { LibLoader::load_file(path) } { + Ok((l, p)) => return Ok((l, p)), + Err(e) => log::warn!("Plugin {} load fail: {}", path, e), + } + } + bail!("Plugin not found in {:?}", &paths) + } + } + } +} + +struct DynamicPluginStarter { + _lib: Library, + path: PathBuf, + vtable: PluginVTable, +} + +impl + DynamicPluginStarter +{ + fn get_vtable(lib: &Library, path: &Path) -> ZResult> { + log::debug!("Loading plugin {}", &path.to_str().unwrap(),); + let get_plugin_loader_version = + unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; + let plugin_loader_version = get_plugin_loader_version(); + log::debug!("Plugin loader version: {}", &plugin_loader_version); + if plugin_loader_version != PLUGIN_LOADER_VERSION { + bail!( + "Plugin loader version mismatch: host = {}, plugin = {}", + PLUGIN_LOADER_VERSION, + plugin_loader_version + ); + } + let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; + let plugin_compatibility_record = get_compatibility(); + let host_compatibility_record = Compatibility::new::(); + log::debug!( + "Plugin compativilty record: {:?}", + &plugin_compatibility_record + ); + if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { + bail!( + "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", + host_compatibility_record, + plugin_compatibility_record + ); + } + let load_plugin = + unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; + let vtable = load_plugin(); + Ok(vtable) + } + fn new(lib: Library, path: PathBuf) -> ZResult { + let vtable = Self::get_vtable(&lib, &path)?; + Ok(Self { + _lib: lib, + path, + vtable, + }) + } + fn start(&self, name: &str, args: &StartArgs) -> ZResult { + (self.vtable.start)(name, args) + } + fn path(&self) -> &str { + self.path.to_str().unwrap() + } +} + +pub struct DynamicPlugin { + name: String, + condition: PluginCondition, + source: DynamicPluginSource, + starter: Option>, + instance: Option, +} + +impl DynamicPlugin { + pub fn new(name: String, source: DynamicPluginSource) -> Self { + Self { + name, + condition: PluginCondition::new(), + source, + starter: None, + instance: None, + } + } +} + +impl PluginInfo + for DynamicPlugin +{ + fn name(&self) -> &str { + self.name.as_str() + } + fn path(&self) -> &str { + self.starter.as_ref().map_or("", |v| v.path()) + } + fn status(&self) -> PluginStatus { + PluginStatus { + state: if self.starter.is_some() { + if self.instance.is_some() { + PluginState::Started + } else { + PluginState::Loaded + } + } else { + PluginState::Declared + }, + condition: self.condition.clone(), // TODO: request condition from started plugin + } + } +} + +impl DeclaredPlugin + for DynamicPlugin +{ + fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { + if self.starter.is_none() { + let (lib, path) = self.source.load().add_error(&mut self.condition)?; + let starter = DynamicPluginStarter::new(lib, path).add_error(&mut self.condition)?; + self.starter = Some(starter); + } + Ok(self) + } + fn loaded(&self) -> Option<&dyn LoadedPlugin> { + if self.starter.is_some() { + Some(self) + } else { + None + } + } + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { + if self.starter.is_some() { + Some(self) + } else { + None + } + } +} + +impl LoadedPlugin + for DynamicPlugin +{ + fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { + let starter = self + .starter + .as_ref() + .ok_or_else(|| format!("Plugin `{}` not loaded", self.name)) + .add_error(&mut self.condition)?; + let already_started = self.instance.is_some(); + if !already_started { + let instance = starter + .start(self.name(), args) + .add_error(&mut self.condition)?; + self.instance = Some(instance); + } + Ok(self) + } + fn started(&self) -> Option<&dyn StartedPlugin> { + if self.instance.is_some() { + Some(self) + } else { + None + } + } + fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin> { + if self.instance.is_some() { + Some(self) + } else { + None + } + } +} + +impl StartedPlugin + for DynamicPlugin +{ + fn stop(&mut self) { + self.instance = None; + } + fn instance(&self) -> &Instance { + self.instance.as_ref().unwrap() + } + fn instance_mut(&mut self) -> &mut Instance { + self.instance.as_mut().unwrap() + } +} + diff --git a/plugins/zenoh-plugin-trait/src/loading/static_plugin.rs b/plugins/zenoh-plugin-trait/src/loading/static_plugin.rs new file mode 100644 index 0000000000..eb65d0058a --- /dev/null +++ b/plugins/zenoh-plugin-trait/src/loading/static_plugin.rs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use crate::*; +use std::marker::PhantomData; +use zenoh_result::ZResult; + +pub struct StaticPlugin +where + P: Plugin, +{ + instance: Option, + phantom: PhantomData

, +} + +impl StaticPlugin +where + P: Plugin, +{ + pub fn new() -> Self { + Self { + instance: None, + phantom: PhantomData, + } + } +} + +impl PluginInfo for StaticPlugin +where + P: Plugin, +{ + fn name(&self) -> &str { + P::STATIC_NAME + } + fn path(&self) -> &str { + "" + } + fn status(&self) -> PluginStatus { + PluginStatus { + state: self + .instance + .as_ref() + .map_or(PluginState::Loaded, |_| PluginState::Started), + condition: PluginCondition::new(), // TODO: request runnnig plugin status + } + } +} + +impl DeclaredPlugin + for StaticPlugin +where + P: Plugin, +{ + fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { + Ok(self) + } + fn loaded(&self) -> Option<&dyn LoadedPlugin> { + Some(self) + } + fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin> { + Some(self) + } +} + +impl LoadedPlugin + for StaticPlugin +where + P: Plugin, +{ + fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { + if self.instance.is_none() { + self.instance = Some(P::start(self.name(), args)?); + } + Ok(self) + } + fn started(&self) -> Option<&dyn StartedPlugin> { + if self.instance.is_some() { + Some(self) + } else { + None + } + } + fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin> { + if self.instance.is_some() { + Some(self) + } else { + None + } + } +} + +impl StartedPlugin + for StaticPlugin +where + P: Plugin, +{ + fn stop(&mut self) {} + fn instance(&self) -> &Instance { + self.instance.as_ref().unwrap() + } + fn instance_mut(&mut self) -> &mut Instance { + self.instance.as_mut().unwrap() + } +} diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs new file mode 100644 index 0000000000..4ec3fa9d96 --- /dev/null +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -0,0 +1,110 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use std::borrow::Cow; +use zenoh_result::ZResult; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum PluginState { + Declared, + Loaded, + Started, +} + +#[derive(Clone, Debug, PartialEq, Eq, Default)] +pub struct PluginCondition { + warnings: Vec>, + errors: Vec>, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct PluginStatus { + pub state: PluginState, + pub condition: PluginCondition, +} + +pub trait PluginInfo { + fn name(&self) -> &str; + fn path(&self) -> &str; + fn status(&self) -> PluginStatus; +} + +pub trait PluginControl { + fn plugins(&self) -> Vec>; + // fn status(&self, name: &str) -> PluginStatus; +} + +pub trait PluginStructVersion { + /// The version of the structure implementing this trait. After any channge in the structure or it's dependencies + /// whcich may affect the ABI, this version should be incremented. + fn version() -> u64; + /// The features enabled during comiplation of the structure implementing this trait. + /// Different features between the plugin and the host may cuase ABI incompatibility even if the structure version is the same. + /// Use `concat_enabled_features!` to generate this string + fn features() -> &'static str; +} + +pub trait PluginStartArgs: PluginStructVersion {} + +pub trait PluginInstance: PluginStructVersion + PluginControl + Send {} + +pub trait Plugin: Sized + 'static { + type StartArgs: PluginStartArgs; + type Instance: PluginInstance; + /// Your plugins' default name when statically linked. + const STATIC_NAME: &'static str; + /// Starts your plugin. Use `Ok` to return your plugin's control structure + fn start(name: &str, args: &Self::StartArgs) -> ZResult; +} + +impl PluginCondition { + pub fn new() -> Self { + Self::default() + } + pub fn clear(&mut self) { + self.warnings.clear(); + self.errors.clear(); + } + pub fn add_error>>(&mut self, error: S) { + self.errors.push(error.into()); + } + pub fn add_warning>>(&mut self, warning: S) { + self.warnings.push(warning.into()); + } + pub fn errors(&self) -> &[Cow<'static, str>] { + &self.errors + } + pub fn warnings(&self) -> &[Cow<'static, str>] { + &self.warnings + } +} + +pub trait PluginConditionSetter { + fn add_error(self, condition: &mut PluginCondition) -> Self; + fn add_warning(self, condition: &mut PluginCondition) -> Self; +} + +impl PluginConditionSetter for core::result::Result { + fn add_error(self, condition: &mut PluginCondition) -> Self { + if let Err(e) = &self { + condition.add_error(e.to_string()); + } + self + } + fn add_warning(self, condition: &mut PluginCondition) -> Self { + if let Err(e) = &self { + condition.add_warning(e.to_string()); + } + self + } +} diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 6cf16feebd..ec863d73ca 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -13,14 +13,11 @@ // ZettaScale Zenoh Team, // use crate::*; -pub use no_mangle::*; use zenoh_result::ZResult; use std::fmt::Display; pub type PluginLoaderVersion = u64; pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; -pub const FEATURES: &str = - concat_enabled_features!(prefix = "zenoh-plugin-trait", features = ["default"]); type StartFn = fn(&str, &StartArgs) -> ZResult; @@ -28,7 +25,7 @@ type StartFn = fn(&str, &StartArgs) -> ZResult; pub struct PluginVTable { pub start: StartFn, } -impl CompatibilityVersion for PluginVTable { +impl PluginStructVersion for PluginVTable { fn version() -> u64 { 1 } @@ -46,7 +43,7 @@ pub struct StructVersion { } impl StructVersion { - pub fn new() -> Self { + pub fn new() -> Self { Self { version: T::version(), name: std::any::type_name::(), @@ -75,7 +72,7 @@ pub struct Compatibility { } impl Compatibility { - pub fn new() -> Self { + pub fn new() -> Self { let rust_version = RustVersion::new(); let vtable_version = StructVersion::new::>(); let start_args_version = StructVersion::new::(); @@ -176,30 +173,29 @@ impl PluginVTable { pub use no_mangle::*; #[cfg(feature = "no_mangle")] pub mod no_mangle { - /// This macro will add a non-mangled `load_plugin` function to the library if feature `no_mangle` is enabled (which it is by default). + /// This macro will add a non-mangled functions which provides plugin version and loads it if feature `no_mangle` is enabled (which it is by default). #[macro_export] macro_rules! declare_plugin { ($ty: path) => { #[no_mangle] - fn get_plugin_loader_version() -> $crate::prelude::PluginLoaderVersion { - $crate::prelude::PLUGIN_LOADER_VERSION + fn get_plugin_loader_version() -> $crate::PluginLoaderVersion { + $crate::PLUGIN_LOADER_VERSION } #[no_mangle] - fn get_compatibility() -> $crate::prelude::Compatibility { - // TODO: add vtable version (including type parameters) to the compatibility information - $crate::prelude::Compatibility::new::< - <$ty as $crate::prelude::Plugin>::StartArgs, - <$ty as $crate::prelude::Plugin>::Instance, + fn get_compatibility() -> $crate::Compatibility { + $crate::Compatibility::new::< + <$ty as $crate::Plugin>::StartArgs, + <$ty as $crate::Plugin>::Instance, >() } #[no_mangle] - fn load_plugin() -> $crate::prelude::PluginVTable< - <$ty as $crate::prelude::Plugin>::StartArgs, - <$ty as $crate::prelude::Plugin>::Instance, + fn load_plugin() -> $crate::PluginVTable< + <$ty as $crate::Plugin>::StartArgs, + <$ty as $crate::Plugin>::Instance, > { - $crate::prelude::PluginVTable::new::<$ty>() + $crate::PluginVTable::new::<$ty>() } }; } diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 1347efdd57..054a7421d0 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -37,7 +37,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::{CompatibilityVersion, PluginStartArgs}; +use zenoh_plugin_trait::{PluginStructVersion, PluginStartArgs}; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; @@ -65,7 +65,7 @@ pub struct Runtime { state: Arc, } -impl CompatibilityVersion for Runtime { +impl PluginStructVersion for Runtime { fn version() -> u64 { 1 } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 14c658a99c..3c61e40b75 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -33,7 +33,7 @@ pub type StartArgs = Runtime; /// A zenoh plugin, when started, must return this type. pub type RunningPlugin = Box; -impl CompatibilityVersion for RunningPlugin { +impl PluginStructVersion for RunningPlugin { fn version() -> u64 { 1 } @@ -92,9 +92,9 @@ pub trait RunningPluginTrait: Send + Sync { } /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. -pub type PluginsManager = zenoh_plugin_trait::loading::PluginsManager; +pub type PluginsManager = zenoh_plugin_trait::PluginsManager; -pub use zenoh_plugin_trait::CompatibilityVersion; +pub use zenoh_plugin_trait::PluginStructVersion; pub use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginInstance; From 9957d444b35ad19514eedda12b8b2807ec50cc95 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 10 Nov 2023 15:52:02 +0100 Subject: [PATCH 042/106] get plugin names list recursively --- plugins/example-plugin/src/lib.rs | 4 ++ plugins/zenoh-backend-traits/src/lib.rs | 3 +- plugins/zenoh-plugin-rest/src/lib.rs | 4 ++ .../zenoh-plugin-storage-manager/src/lib.rs | 8 ++++ plugins/zenoh-plugin-trait/src/loading.rs | 40 ++++++++++++++++--- plugins/zenoh-plugin-trait/src/plugin.rs | 2 +- zenoh/src/plugins/sealed.rs | 10 +---- 7 files changed, 54 insertions(+), 17 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index bed5b98e47..d52594588c 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -15,6 +15,7 @@ use futures::select; use log::{debug, info}; +use zenoh_plugin_trait::PluginControl; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{ @@ -85,6 +86,9 @@ struct RunningPluginInner { // The RunningPlugin struct implementing the RunningPluginTrait trait #[derive(Clone)] struct RunningPlugin(Arc>); + +impl PluginControl for RunningPlugin {} + impl RunningPluginTrait for RunningPlugin { fn config_checker( &self, diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 03ad09253c..3e1672dece 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -133,7 +133,6 @@ use async_trait::async_trait; use const_format::concatcp; -use std::borrow::Cow; use std::sync::Arc; use zenoh::prelude::{KeyExpr, OwnedKeyExpr, Sample, Selector}; use zenoh::queryable::ReplyBuilder; @@ -234,7 +233,7 @@ impl PluginStructVersion for VolumePlugin { } impl PluginControl for VolumePlugin { - fn plugins(&self) -> Vec> { + fn plugins(&self) -> Vec { Vec::new() } } diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 3cb12d290d..93043c34f9 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -21,6 +21,7 @@ use async_std::prelude::FutureExt; use base64::{engine::general_purpose::STANDARD as b64_std_engine, Engine}; use futures::StreamExt; use http_types::Method; +use zenoh_plugin_trait::PluginControl; use std::convert::TryFrom; use std::str::FromStr; use std::sync::Arc; @@ -242,6 +243,9 @@ impl Plugin for RestPlugin { } struct RunningPlugin(Config); + +impl PluginControl for RunningPlugin {} + impl RunningPluginTrait for RunningPlugin { fn config_checker( &self, diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 7d1d762a16..c8e9165ff8 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -22,6 +22,7 @@ use async_std::task; use flume::Sender; use memory_backend::MemoryBackend; +use zenoh_plugin_trait::PluginControl; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::Arc; @@ -220,6 +221,13 @@ impl From for StorageRuntime { } } +impl PluginControl for StorageRuntime { + fn plugins(&self) -> Vec { + let guard = self.0.lock().unwrap(); + guard.plugins_manager.plugins() + } +} + impl RunningPluginTrait for StorageRuntime { fn config_checker( &self, diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 81b744807c..91096b3aa5 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -10,14 +10,17 @@ // Contributors: // ZettaScale Zenoh Team, // -mod static_plugin; mod dynamic_plugin; +mod static_plugin; use crate::*; use zenoh_result::ZResult; use zenoh_util::LibLoader; -use self::{dynamic_plugin::{DynamicPlugin, DynamicPluginSource}, static_plugin::StaticPlugin}; +use self::{ + dynamic_plugin::{DynamicPlugin, DynamicPluginSource}, + static_plugin::StaticPlugin, +}; pub trait DeclaredPlugin: PluginInfo { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin>; @@ -151,14 +154,14 @@ impl } /// Lists all plugins - pub fn plugins(&self) -> impl Iterator> + '_ { + pub fn declared_plugins(&self) -> impl Iterator> + '_ { self.plugins .iter() .map(|p| p as &dyn DeclaredPlugin) } /// Lists all plugins mutable - pub fn plugins_mut( + pub fn declared_plugins_mut( &mut self, ) -> impl Iterator> + '_ { self.plugins @@ -170,7 +173,7 @@ impl pub fn loaded_plugins( &self, ) -> impl Iterator> + '_ { - self.plugins().filter_map(|p| p.loaded()) + self.declared_plugins().filter_map(|p| p.loaded()) } /// Lists the loaded plugins mutable @@ -178,7 +181,7 @@ impl &mut self, ) -> impl Iterator> + '_ { // self.plugins_mut().filter_map(|p| p.loaded_mut()) - self.plugins_mut().filter_map(|p| p.loaded_mut()) + self.declared_plugins_mut().filter_map(|p| p.loaded_mut()) } /// Lists the started plugins @@ -236,3 +239,28 @@ impl self.loaded_plugin_mut(name)?.started_mut() } } + +impl PluginControl + for PluginsManager +{ + fn plugins(&self) -> Vec { + let mut plugins = Vec::new(); + for plugin in self.declared_plugins() { + plugins.push(plugin.name().to_string()); + // for running plugins append their subplugins prepended with the running plugin name + if let Some(plugin) = plugin.loaded() { + if let Some(plugin) = plugin.started() { + plugins.append( + &mut plugin + .instance() + .plugins() + .iter() + .map(|p| format!("{}/{}", plugin.name(), p)) + .collect::>(), + ); + } + } + } + plugins + } +} diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 4ec3fa9d96..e76a954518 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -40,7 +40,7 @@ pub trait PluginInfo { } pub trait PluginControl { - fn plugins(&self) -> Vec>; + fn plugins(&self) -> Vec { Vec::new() } // fn status(&self, name: &str) -> PluginStatus; } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 3c61e40b75..ec9e05a6e1 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -14,8 +14,6 @@ //! `zenohd`'s plugin system. For more details, consult the [detailed documentation](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Plugins/Zenoh%20Plugins.md). -use std::borrow::Cow; - use crate::prelude::Selector; pub use crate::runtime::Runtime; pub use crate::Result as ZResult; @@ -42,11 +40,7 @@ impl PluginStructVersion for RunningPlugin { } } -impl PluginControl for RunningPlugin { - fn plugins(&self) -> Vec> { - Vec::new() - } -} +impl PluginControl for RunningPlugin {} impl PluginInstance for RunningPlugin {} @@ -64,7 +58,7 @@ impl Response { } } -pub trait RunningPluginTrait: Send + Sync { +pub trait RunningPluginTrait: Send + Sync + PluginControl { /// Function that will be called when configuration relevant to the plugin is about to change. /// /// This function is called with 3 arguments: From 7e586cbaca429a83129db4eda6a4cebd0a7f85f4 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 13 Nov 2023 11:25:09 +0100 Subject: [PATCH 043/106] pligins method unifinshed --- Cargo.lock | 1 + plugins/example-plugin/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/Cargo.toml | 1 + plugins/zenoh-plugin-trait/src/loading.rs | 22 +++++++++--------- plugins/zenoh-plugin-trait/src/plugin.rs | 28 +++++++++++++++++++++-- 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7c5d31328..874818dfc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4955,6 +4955,7 @@ dependencies = [ "libloading", "log", "serde_json", + "zenoh-keyexpr", "zenoh-macros", "zenoh-result", "zenoh-util", diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index d52594588c..be50a2ce5a 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -15,7 +15,6 @@ use futures::select; use log::{debug, info}; -use zenoh_plugin_trait::PluginControl; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{ @@ -26,6 +25,7 @@ use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; +use zenoh_plugin_trait::PluginControl; use zenoh_result::{bail, ZResult}; // The struct implementing the ZenohPlugin and ZenohPlugin traits diff --git a/plugins/zenoh-plugin-trait/Cargo.toml b/plugins/zenoh-plugin-trait/Cargo.toml index 2a45c7f6cf..a8389a0c54 100644 --- a/plugins/zenoh-plugin-trait/Cargo.toml +++ b/plugins/zenoh-plugin-trait/Cargo.toml @@ -37,4 +37,5 @@ serde_json = { workspace = true } zenoh-macros = { workspace = true } zenoh-result = { workspace = true } zenoh-util = { workspace = true } +zenoh-keyexpr = { workspace = true } const_format = { workspace = true } \ No newline at end of file diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 91096b3aa5..2ea734c0b7 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -14,6 +14,7 @@ mod dynamic_plugin; mod static_plugin; use crate::*; +use zenoh_keyexpr::keyexpr; use zenoh_result::ZResult; use zenoh_util::LibLoader; @@ -154,7 +155,9 @@ impl } /// Lists all plugins - pub fn declared_plugins(&self) -> impl Iterator> + '_ { + pub fn declared_plugins( + &self, + ) -> impl Iterator> + '_ { self.plugins .iter() .map(|p| p as &dyn DeclaredPlugin) @@ -243,21 +246,18 @@ impl impl PluginControl for PluginsManager { - fn plugins(&self) -> Vec { + fn plugins(&self, prefix: &keyexpr, names: &keyexpr) -> Vec<(String, PluginStatus)> { let mut plugins = Vec::new(); for plugin in self.declared_plugins() { - plugins.push(plugin.name().to_string()); + let name = prefix.join(plugin.name()).unwrap(); + let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; + if names.includes(name) { + plugins.push((plugin.name().to_string(), plugin.status())); + } // for running plugins append their subplugins prepended with the running plugin name if let Some(plugin) = plugin.loaded() { if let Some(plugin) = plugin.started() { - plugins.append( - &mut plugin - .instance() - .plugins() - .iter() - .map(|p| format!("{}/{}", plugin.name(), p)) - .collect::>(), - ); + plugins.append(&mut plugin.instance().plugins(names)); } } } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index e76a954518..3c9bb4ce0f 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // use std::borrow::Cow; +use zenoh_keyexpr::keyexpr; use zenoh_result::ZResult; #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -40,8 +41,31 @@ pub trait PluginInfo { } pub trait PluginControl { - fn plugins(&self) -> Vec { Vec::new() } - // fn status(&self, name: &str) -> PluginStatus; + fn condition(&self) -> PluginCondition { + PluginCondition::default() + } + /// Collect information of sub-plugins matching `_names` keyexpr excluding `_prefix` part + /// The prefix parameter allows to pass a request to plugins tree without changing the request. + /// + /// For example: + /// - when request is "@/router/XXXX/plugins/**", it's passed to root plugin manager as + /// `plugins("@/router/XXXX/plugins", "@/router/XXXX/plugins/**")` + /// - for plugin named `storages` the combined name is `@/router/XXXX/plugins/storages` which matches the request + /// - for sub-plugins of"storages" plugin the root manager calls + /// `plugins("@/router/XXXX/plugins/storages", "@/router/XXXX/plugins/**")` + /// + /// Another example: + /// - when request is "@/router/XXXX/plugins/*/memory", it's passed to root plugin manager as + /// `plugins("@/router/XXXX/plugins", "@/router/XXXX/plugins/*/memory")` + /// - storages plugin itself doesn't match the request: `@/router/XXXX/plugins/storages` doesn't match `@/router/XXXX/plugins/*/memory` + /// - request is passed to storages plugin anyway as + /// `plugins("@/router/XXXX/plugins/storages", "@/router/XXXX/plugins/*/memory")` + /// - subplugin "memory" matches the request: `@/router/XXXX/plugins/storages/memory` matches `@/router/XXXX/plugins/*/memory` + /// + /// I.e. it's important that all items of plugin tree are checked for matching the request, no matter if parent plugin matches it or not. + fn plugins(&self, _prefix: &keyexpr, _names: &keyexpr) -> Vec<(String, PluginStatus)> { + Vec::new() + } } pub trait PluginStructVersion { From 0cf6ca49b462534ac26b5632eb6d63186dfcf7aa Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 13 Nov 2023 17:33:29 +0100 Subject: [PATCH 044/106] strip_prefix --- plugins/zenoh-backend-traits/src/lib.rs | 4 ++-- .../zenoh-plugin-storage-manager/src/lib.rs | 9 ++++++-- plugins/zenoh-plugin-trait/src/loading.rs | 7 +++--- plugins/zenoh-plugin-trait/src/plugin.rs | 22 ++----------------- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 3e1672dece..18f2b69ef5 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -139,7 +139,7 @@ use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; -use zenoh_plugin_trait::{concat_enabled_features, PluginStructVersion, PluginControl, PluginInstance}; +use zenoh_plugin_trait::{concat_enabled_features, PluginStructVersion, PluginControl, PluginInstance, PluginStatus}; pub mod config; use config::{StorageConfig, VolumeConfig}; @@ -233,7 +233,7 @@ impl PluginStructVersion for VolumePlugin { } impl PluginControl for VolumePlugin { - fn plugins(&self) -> Vec { + fn plugins(&self, _names: &zenoh::prelude::keyexpr) -> Vec<(String, PluginStatus)> { Vec::new() } } diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index c8e9165ff8..d06fc7b1d9 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -22,7 +22,9 @@ use async_std::task; use flume::Sender; use memory_backend::MemoryBackend; +use zenoh_plugin_trait::PluginCondition; use zenoh_plugin_trait::PluginControl; +use zenoh_plugin_trait::PluginStatus; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::Arc; @@ -222,9 +224,12 @@ impl From for StorageRuntime { } impl PluginControl for StorageRuntime { - fn plugins(&self) -> Vec { + fn condition(&self) -> PluginCondition { + PluginCondition::default() + } + fn plugins(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { let guard = self.0.lock().unwrap(); - guard.plugins_manager.plugins() + guard.plugins_manager.plugins(names) } } diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 2ea734c0b7..08c928fd3b 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -246,10 +246,9 @@ impl impl PluginControl for PluginsManager { - fn plugins(&self, prefix: &keyexpr, names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { let mut plugins = Vec::new(); for plugin in self.declared_plugins() { - let name = prefix.join(plugin.name()).unwrap(); let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; if names.includes(name) { plugins.push((plugin.name().to_string(), plugin.status())); @@ -257,7 +256,9 @@ impl P // for running plugins append their subplugins prepended with the running plugin name if let Some(plugin) = plugin.loaded() { if let Some(plugin) = plugin.started() { - plugins.append(&mut plugin.instance().plugins(names)); + if let [names, ..] = names.strip_prefix(name)[..] { + plugins.append(&mut plugin.instance().plugins(names)); + } } } } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 3c9bb4ce0f..b53a41abe4 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -44,26 +44,8 @@ pub trait PluginControl { fn condition(&self) -> PluginCondition { PluginCondition::default() } - /// Collect information of sub-plugins matching `_names` keyexpr excluding `_prefix` part - /// The prefix parameter allows to pass a request to plugins tree without changing the request. - /// - /// For example: - /// - when request is "@/router/XXXX/plugins/**", it's passed to root plugin manager as - /// `plugins("@/router/XXXX/plugins", "@/router/XXXX/plugins/**")` - /// - for plugin named `storages` the combined name is `@/router/XXXX/plugins/storages` which matches the request - /// - for sub-plugins of"storages" plugin the root manager calls - /// `plugins("@/router/XXXX/plugins/storages", "@/router/XXXX/plugins/**")` - /// - /// Another example: - /// - when request is "@/router/XXXX/plugins/*/memory", it's passed to root plugin manager as - /// `plugins("@/router/XXXX/plugins", "@/router/XXXX/plugins/*/memory")` - /// - storages plugin itself doesn't match the request: `@/router/XXXX/plugins/storages` doesn't match `@/router/XXXX/plugins/*/memory` - /// - request is passed to storages plugin anyway as - /// `plugins("@/router/XXXX/plugins/storages", "@/router/XXXX/plugins/*/memory")` - /// - subplugin "memory" matches the request: `@/router/XXXX/plugins/storages/memory` matches `@/router/XXXX/plugins/*/memory` - /// - /// I.e. it's important that all items of plugin tree are checked for matching the request, no matter if parent plugin matches it or not. - fn plugins(&self, _prefix: &keyexpr, _names: &keyexpr) -> Vec<(String, PluginStatus)> { + /// Collect information of sub-plugins matching `_names` keyexpr + fn plugins(&self, _names: &keyexpr) -> Vec<(String, PluginStatus)> { Vec::new() } } From 19a3c6801e16f254993e8c3fc8653188d28858fb Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 13 Nov 2023 18:45:57 +0100 Subject: [PATCH 045/106] adminspace --- plugins/zenoh-backend-traits/src/lib.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 4 ++-- plugins/zenoh-plugin-trait/src/loading.rs | 4 ++-- plugins/zenoh-plugin-trait/src/plugin.rs | 2 +- zenoh/src/net/runtime/adminspace.rs | 18 ++++++++++++++++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 18f2b69ef5..6bb9f9c0a0 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -233,7 +233,7 @@ impl PluginStructVersion for VolumePlugin { } impl PluginControl for VolumePlugin { - fn plugins(&self, _names: &zenoh::prelude::keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, _names: &zenoh::prelude::keyexpr) -> Vec<(String, PluginStatus)> { Vec::new() } } diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index d06fc7b1d9..83da786738 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -227,9 +227,9 @@ impl PluginControl for StorageRuntime { fn condition(&self) -> PluginCondition { PluginCondition::default() } - fn plugins(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { let guard = self.0.lock().unwrap(); - guard.plugins_manager.plugins(names) + guard.plugins_manager.plugins_status(names) } } diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/loading.rs index 08c928fd3b..d3e03d288c 100644 --- a/plugins/zenoh-plugin-trait/src/loading.rs +++ b/plugins/zenoh-plugin-trait/src/loading.rs @@ -246,7 +246,7 @@ impl impl PluginControl for PluginsManager { - fn plugins(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { let mut plugins = Vec::new(); for plugin in self.declared_plugins() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; @@ -257,7 +257,7 @@ impl P if let Some(plugin) = plugin.loaded() { if let Some(plugin) = plugin.started() { if let [names, ..] = names.strip_prefix(name)[..] { - plugins.append(&mut plugin.instance().plugins(names)); + plugins.append(&mut plugin.instance().plugins_status(names)); } } } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index b53a41abe4..a5f28c77a8 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -45,7 +45,7 @@ pub trait PluginControl { PluginCondition::default() } /// Collect information of sub-plugins matching `_names` keyexpr - fn plugins(&self, _names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, _names: &keyexpr) -> Vec<(String, PluginStatus)> { Vec::new() } } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index fb937e3bb8..a4d56fad93 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -21,6 +21,8 @@ use crate::value::Value; use async_std::task; use log::{error, trace}; use serde_json::json; +use zenoh_plugin_trait::PluginControl; +use zenoh_protocol::core::key_expr::keyexpr; use std::collections::HashMap; use std::convert::TryFrom; use std::convert::TryInto; @@ -157,6 +159,12 @@ impl AdminSpace { .unwrap(), Arc::new(queryables_data), ); + handlers.insert( + format!("@/router/{zid_str}/plugins/**") + .try_into() + .unwrap(), + Arc::new(plugins_data), + ); handlers.insert( format!("@/router/{zid_str}/status/plugins/**") .try_into() @@ -650,6 +658,16 @@ fn queryables_data(context: &AdminContext, query: Query) { } } +fn plugins_data(context: &AdminContext, query: Query) { + let guard = zlock!(context.plugins_mgr); + let root_key = format!("@/router/{}/plugins", &context.zid_str); + let root_key = unsafe { keyexpr::from_str_unchecked(&root_key) }; + if let [names,..] = query.key_expr().strip_prefix(root_key)[..] { + let statuses = guard.plugins_status(names); + log::info!("Statuses: {:?}", statuses); + } +} + fn plugins_status(context: &AdminContext, query: Query) { let selector = query.selector(); let guard = zlock!(context.plugins_mgr); From 131754499f52dc6b9317783f1d1f6c492ee0dba6 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 14 Nov 2023 13:53:15 +0100 Subject: [PATCH 046/106] renamed loading to manager --- plugins/zenoh-plugin-trait/src/lib.rs | 4 ++-- plugins/zenoh-plugin-trait/src/{loading.rs => manager.rs} | 0 .../src/{loading => manager}/dynamic_plugin.rs | 0 .../src/{loading => manager}/static_plugin.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename plugins/zenoh-plugin-trait/src/{loading.rs => manager.rs} (100%) rename plugins/zenoh-plugin-trait/src/{loading => manager}/dynamic_plugin.rs (100%) rename plugins/zenoh-plugin-trait/src/{loading => manager}/static_plugin.rs (100%) diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 6c6be740d1..bd3d1a7c15 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -19,11 +19,11 @@ //! If building a plugin for [`zenohd`](https://crates.io/crates/zenoh), you should use the types exported in [`zenoh::plugins`](https://docs.rs/zenoh/latest/zenoh/plugins) to fill [`Plugin`]'s associated types. //! To check your plugin typing for `zenohd`, have your plugin implement [`zenoh::plugins::ZenohPlugin`](https://docs.rs/zenoh/latest/zenoh/plugins/struct.ZenohPlugin) //! -mod loading; +mod manager; mod plugin; mod vtable; -pub use loading::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; +pub use manager::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; pub use plugin::{ Plugin, PluginCondition, PluginConditionSetter, PluginControl, PluginInfo, PluginInstance, PluginStartArgs, PluginState, PluginStatus, PluginStructVersion, diff --git a/plugins/zenoh-plugin-trait/src/loading.rs b/plugins/zenoh-plugin-trait/src/manager.rs similarity index 100% rename from plugins/zenoh-plugin-trait/src/loading.rs rename to plugins/zenoh-plugin-trait/src/manager.rs diff --git a/plugins/zenoh-plugin-trait/src/loading/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs similarity index 100% rename from plugins/zenoh-plugin-trait/src/loading/dynamic_plugin.rs rename to plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs diff --git a/plugins/zenoh-plugin-trait/src/loading/static_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs similarity index 100% rename from plugins/zenoh-plugin-trait/src/loading/static_plugin.rs rename to plugins/zenoh-plugin-trait/src/manager/static_plugin.rs From d850216ee1076d3c0bd759cab9c6137d5efa2807 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 14 Nov 2023 16:41:56 +0100 Subject: [PATCH 047/106] log prints, recurse info --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 15 ++++++++++++--- plugins/zenoh-plugin-trait/src/manager.rs | 15 ++++++++++----- .../src/manager/dynamic_plugin.rs | 7 +++++++ .../src/manager/static_plugin.rs | 8 +++++++- zenoh/src/net/runtime/adminspace.rs | 4 ++-- zenoh/src/plugins/sealed.rs | 13 ++++++++++++- zenohd/src/main.rs | 4 ++-- 7 files changed, 52 insertions(+), 14 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 83da786738..49e483f3f4 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -112,7 +112,7 @@ impl StorageRuntimeInner { let session = Arc::new(zenoh::init(runtime.clone()).res_sync().unwrap()); let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX) - .add_static_plugin::(); + .declare_static_plugin::(); let mut new_self = StorageRuntimeInner { name, @@ -151,6 +151,7 @@ impl StorageRuntimeInner { } fn kill_volume>(&mut self, name: T) -> ZResult<()> { let name = name.as_ref(); + log::info!("Killing volume {}", name); if let Some(storages) = self.storages.remove(name) { async_std::task::block_on(futures::future::join_all( storages @@ -167,13 +168,14 @@ impl StorageRuntimeInner { fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); + log::info!("Spawning volume {} with backend {}", volume_id, backend_name); let declared = if let Some(declared) = self.plugins_manager.plugin_mut(volume_id) { declared } else if let Some(paths) = config.paths() { - self.plugins_manager.add_dynamic_plugin_by_paths(volume_id, paths)? + self.plugins_manager.declare_dynamic_plugin_by_paths(volume_id, paths)? } else { self.plugins_manager - .add_dynamic_plugin_by_name(volume_id, backend_name)? + .declare_dynamic_plugin_by_name(volume_id, backend_name)? }; let loaded = declared.load()?; loaded.start(&config)?; @@ -181,6 +183,7 @@ impl StorageRuntimeInner { } fn kill_storage(&mut self, config: StorageConfig) { let volume = &config.volume_id; + log::info!("Killing storage {} from volume {}", config.name, volume); if let Some(storages) = self.storages.get_mut(volume) { if let Some(storage) = storages.get_mut(&config.name) { log::debug!( @@ -200,6 +203,12 @@ impl StorageRuntimeInner { format!("Cannot find volume {} to spawn storage {}", volume_id, storage.name), )?; let storage_name = storage.name.clone(); + log::info!( + "Spawning storage {} from volume {} with backend {}", + storage_name, + volume_id, + backend.name() + ); let in_interceptor = backend.instance().incoming_data_interceptor(); let out_interceptor = backend.instance().outgoing_data_interceptor(); let stopper = async_std::task::block_on(create_and_start_storage( diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index d3e03d288c..dd01b2cdb9 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -107,30 +107,33 @@ impl } /// Adds a statically linked plugin to the manager. - pub fn add_static_plugin< + pub fn declare_static_plugin< P: Plugin + Send + Sync, >( mut self, ) -> Self { let plugin_loader: StaticPlugin = StaticPlugin::new(); self.plugins.push(PluginRecord::new(plugin_loader)); + log::debug!("Declared static plugin {}", self.plugins.last().unwrap().name()); self } /// Add dynamic plugin to the manager by name, automatically prepending the default library prefix - pub fn add_dynamic_plugin_by_name>( + pub fn declare_dynamic_plugin_by_name>( &mut self, name: S, plugin_name: &str, ) -> ZResult<&mut dyn DeclaredPlugin> { + let name = name.into(); let plugin_name = format!("{}{}", self.default_lib_prefix, plugin_name); let libloader = self .loader .as_ref() .ok_or("Dynamic plugin loading is disabled")? .clone(); + log::debug!("Declared dynamic plugin {} by name {}", &name, &plugin_name); let loader = DynamicPlugin::new( - name.into(), + name, DynamicPluginSource::ByName((libloader, plugin_name)), ); self.plugins.push(PluginRecord::new(loader)); @@ -138,13 +141,14 @@ impl } /// Add first available dynamic plugin from the list of paths to the plugin files - pub fn add_dynamic_plugin_by_paths, P: AsRef + std::fmt::Debug>( + pub fn declare_dynamic_plugin_by_paths, P: AsRef + std::fmt::Debug>( &mut self, name: S, paths: &[P], ) -> ZResult<&mut dyn DeclaredPlugin> { let name = name.into(); let paths = paths.iter().map(|p| p.as_ref().into()).collect(); + log::debug!("Declared dynamic plugin {} by paths {:?}", &name, &paths); let loader = DynamicPlugin::new(name, DynamicPluginSource::ByPaths(paths)); self.plugins.push(PluginRecord::new(loader)); Ok(self.plugins.last_mut().unwrap()) @@ -247,6 +251,7 @@ impl P for PluginsManager { fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + log::debug!("Plugin manager with prefix `{}` : requested plugins_status {:?}", self.default_lib_prefix , names); let mut plugins = Vec::new(); for plugin in self.declared_plugins() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; @@ -257,7 +262,7 @@ impl P if let Some(plugin) = plugin.loaded() { if let Some(plugin) = plugin.started() { if let [names, ..] = names.strip_prefix(name)[..] { - plugins.append(&mut plugin.instance().plugins_status(names)); + plugins.append(&mut plugin.instance().plugins_status(names).iter().map(|(n, s)| (format!("{}/{}", name, n), s.clone())).collect()); } } } diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index 898016e1be..cfa0b25887 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -155,7 +155,10 @@ impl DeclaredPlugin LoadedPlugin StartedPlugin { fn stop(&mut self) { + log::debug!("Plugin `{}` stopped", self.name); self.instance = None; } fn instance(&self) -> &Instance { diff --git a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs index eb65d0058a..6268d9a52d 100644 --- a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs @@ -79,7 +79,10 @@ where { fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { if self.instance.is_none() { + log::debug!("Plugin `{}` started", self.name()); self.instance = Some(P::start(self.name(), args)?); + } else { + log::warn!("Plugin `{}` already started", self.name()); } Ok(self) } @@ -104,7 +107,10 @@ impl StartedPlugin where P: Plugin, { - fn stop(&mut self) {} + fn stop(&mut self) { + log::debug!("Plugin `{}` stopped", self.name()); + self.instance = None; + } fn instance(&self) -> &Instance { self.instance.as_ref().unwrap() } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index a4d56fad93..91e3d87218 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -94,9 +94,9 @@ impl AdminSpace { log::warn!("Plugin `{}` was already declared", declared.name()); declared } else if let Some(paths) = &config.paths { - plugin_mgr.add_dynamic_plugin_by_paths(name, paths)? + plugin_mgr.declare_dynamic_plugin_by_paths(name, paths)? } else { - plugin_mgr.add_dynamic_plugin_by_name(name, name)? + plugin_mgr.declare_dynamic_plugin_by_name(name, name)? }; let loaded = if let Some(loaded) = declared.loaded_mut() { diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index ec9e05a6e1..4fff35eea8 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -40,7 +40,15 @@ impl PluginStructVersion for RunningPlugin { } } -impl PluginControl for RunningPlugin {} +impl PluginControl for RunningPlugin { + fn condition(&self) -> PluginCondition { + self.as_ref().condition() + } + + fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + self.as_ref().plugins_status(names) + } +} impl PluginInstance for RunningPlugin {} @@ -88,7 +96,10 @@ pub trait RunningPluginTrait: Send + Sync + PluginControl { /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. pub type PluginsManager = zenoh_plugin_trait::PluginsManager; +use zenoh_plugin_trait::PluginCondition; +use zenoh_plugin_trait::PluginStatus; pub use zenoh_plugin_trait::PluginStructVersion; pub use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginInstance; +use zenoh_protocol::core::key_expr::keyexpr; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 3bd126ef69..087e4be87f 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -39,9 +39,9 @@ fn load_plugin( log::warn!("Plugin `{}` was already declared", declared.name()); declared } else if let Some(paths) = paths { - plugin_mgr.add_dynamic_plugin_by_paths(name, paths)? + plugin_mgr.declare_dynamic_plugin_by_paths(name, paths)? } else { - plugin_mgr.add_dynamic_plugin_by_name(name, name)? + plugin_mgr.declare_dynamic_plugin_by_name(name, name)? }; if let Some(loaded) = declared.loaded_mut() { From 50564bbed4fd6415d38b2c43b625a77d26893369 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 14 Nov 2023 17:15:24 +0100 Subject: [PATCH 048/106] adminspace works --- Cargo.lock | 1 + plugins/zenoh-plugin-trait/Cargo.toml | 1 + plugins/zenoh-plugin-trait/src/plugin.rs | 7 ++++--- zenoh/src/net/runtime/adminspace.rs | 26 +++++++++++++++++------- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 874818dfc0..1f214b5023 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4954,6 +4954,7 @@ dependencies = [ "const_format", "libloading", "log", + "serde", "serde_json", "zenoh-keyexpr", "zenoh-macros", diff --git a/plugins/zenoh-plugin-trait/Cargo.toml b/plugins/zenoh-plugin-trait/Cargo.toml index a8389a0c54..679feba9a1 100644 --- a/plugins/zenoh-plugin-trait/Cargo.toml +++ b/plugins/zenoh-plugin-trait/Cargo.toml @@ -33,6 +33,7 @@ no_mangle = [] [dependencies] libloading = { workspace = true } log = { workspace = true } +serde = { workspace = true } serde_json = { workspace = true } zenoh-macros = { workspace = true } zenoh-result = { workspace = true } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index a5f28c77a8..fd2c03369a 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -14,21 +14,22 @@ use std::borrow::Cow; use zenoh_keyexpr::keyexpr; use zenoh_result::ZResult; +use serde::{Deserialize, Serialize}; -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum PluginState { Declared, Loaded, Started, } -#[derive(Clone, Debug, PartialEq, Eq, Default)] +#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] pub struct PluginCondition { warnings: Vec>, errors: Vec>, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PluginStatus { pub state: PluginState, pub condition: PluginCondition, diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 91e3d87218..5fe15be8d3 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -21,8 +21,6 @@ use crate::value::Value; use async_std::task; use log::{error, trace}; use serde_json::json; -use zenoh_plugin_trait::PluginControl; -use zenoh_protocol::core::key_expr::keyexpr; use std::collections::HashMap; use std::convert::TryFrom; use std::convert::TryInto; @@ -30,6 +28,8 @@ use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::SplitBuffer; use zenoh_config::{ConfigValidator, ValidatedMap}; +use zenoh_plugin_trait::PluginControl; +use zenoh_protocol::core::key_expr::keyexpr; use zenoh_protocol::{ core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, network::{ @@ -160,9 +160,7 @@ impl AdminSpace { Arc::new(queryables_data), ); handlers.insert( - format!("@/router/{zid_str}/plugins/**") - .try_into() - .unwrap(), + format!("@/router/{zid_str}/plugins/**").try_into().unwrap(), Arc::new(plugins_data), ); handlers.insert( @@ -662,9 +660,23 @@ fn plugins_data(context: &AdminContext, query: Query) { let guard = zlock!(context.plugins_mgr); let root_key = format!("@/router/{}/plugins", &context.zid_str); let root_key = unsafe { keyexpr::from_str_unchecked(&root_key) }; - if let [names,..] = query.key_expr().strip_prefix(root_key)[..] { + log::debug!("requested plugins status {:?}", query.key_expr()); + if let [names, ..] = query.key_expr().strip_prefix(root_key)[..] { let statuses = guard.plugins_status(names); - log::info!("Statuses: {:?}", statuses); + for (name, status) in statuses { + log::debug!("plugin {} status: {:?}", name, status); + let key = root_key.join(&name).unwrap(); + let status = serde_json::to_value(status).unwrap(); + if let Err(e) = query + .reply(Ok(Sample::new( + key, + Value::from(status) + ))) + .res() + { + log::error!("Error sending AdminSpace reply: {:?}", e); + } + } } } From 7a49a71ea085c946de1a46408bb09423e5f09127 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 14 Nov 2023 18:27:08 +0100 Subject: [PATCH 049/106] fixed compilation of example-plugin --- DEFAULT_CONFIG.json5 | 6 +++++- plugins/example-plugin/Cargo.toml | 6 +++++- plugins/example-plugin/src/lib.rs | 5 +++-- plugins/zenoh-plugin-rest/src/lib.rs | 4 ++-- plugins/zenoh-plugin-storage-manager/src/lib.rs | 3 ++- plugins/zenoh-plugin-trait/src/plugin.rs | 2 ++ zenoh/src/plugins/sealed.rs | 16 ++++++++-------- 7 files changed, 27 insertions(+), 15 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index 1ff25a0c22..a98434f78c 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -400,7 +400,11 @@ }, storage_manager: { __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - } + }, + not_found: { + }, + example: { + }, }, } diff --git a/plugins/example-plugin/Cargo.toml b/plugins/example-plugin/Cargo.toml index 82cdeba6e5..40665afef4 100644 --- a/plugins/example-plugin/Cargo.toml +++ b/plugins/example-plugin/Cargo.toml @@ -18,6 +18,10 @@ version = { workspace = true } authors = { workspace = true } edition = { workspace = true } +[features] +default = ["no_mangle"] +no_mangle = ["zenoh-plugin-trait/no_mangle"] + [lib] # When auto-detecting the "example" plugin, `zenohd` will look for a dynamic library named "zenoh_plugin_example" # `zenohd` will expect the file to be named according to OS conventions: @@ -35,7 +39,7 @@ env_logger = { workspace = true } futures = { workspace = true } log = { workspace = true } serde_json = { workspace = true } -zenoh = { workspace = true } +zenoh = { workspace = true, features = [ "unstable" ] } zenoh-core = { workspace = true } zenoh-plugin-trait = { workspace = true } zenoh-result = { workspace = true } diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index be50a2ce5a..513a81bf4f 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -15,17 +15,17 @@ use futures::select; use log::{debug, info}; +use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{ atomic::{AtomicBool, Ordering::Relaxed}, Arc, Mutex, }; -use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; -use zenoh_plugin_trait::PluginControl; +use zenoh_plugin_trait::{PluginControl, Plugin}; use zenoh_result::{bail, ZResult}; // The struct implementing the ZenohPlugin and ZenohPlugin traits @@ -48,6 +48,7 @@ impl Plugin for ExamplePlugin { // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { + bail!("Tra-ta-ta"); let config = runtime.config().lock(); let self_cfg = config.plugin(name).unwrap().as_object().unwrap(); // get the plugin's config details from self_cfg Map (here the "storage-selector" property) diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 93043c34f9..eaaaef1887 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -21,14 +21,14 @@ use async_std::prelude::FutureExt; use base64::{engine::general_purpose::STANDARD as b64_std_engine, Engine}; use futures::StreamExt; use http_types::Method; -use zenoh_plugin_trait::PluginControl; +use zenoh_plugin_trait::{PluginControl, Plugin}; use std::convert::TryFrom; use std::str::FromStr; use std::sync::Arc; use tide::http::Mime; use tide::sse::Sender; use tide::{Request, Response, Server, StatusCode}; -use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; +use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::properties::Properties; use zenoh::query::{QueryConsolidation, Reply}; diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 49e483f3f4..3735e0ce1f 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -22,6 +22,7 @@ use async_std::task; use flume::Sender; use memory_backend::MemoryBackend; +use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginCondition; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginStatus; @@ -30,7 +31,7 @@ use std::convert::TryFrom; use std::sync::Arc; use std::sync::Mutex; use storages_mgt::StorageMessage; -use zenoh::plugins::{Plugin, RunningPluginTrait, ZenohPlugin}; +use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::sync::*; use zenoh::runtime::Runtime; use zenoh::Session; diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index fd2c03369a..534ebab794 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -25,7 +25,9 @@ pub enum PluginState { #[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] pub struct PluginCondition { + #[serde(skip_serializing_if = "Vec::is_empty")] warnings: Vec>, + #[serde(skip_serializing_if = "Vec::is_empty")] errors: Vec>, } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 4fff35eea8..e823357646 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -19,6 +19,14 @@ pub use crate::runtime::Runtime; pub use crate::Result as ZResult; use zenoh_core::zconfigurable; +use zenoh_plugin_trait::PluginCondition; +use zenoh_plugin_trait::PluginStatus; +use zenoh_plugin_trait::PluginStructVersion; +use zenoh_plugin_trait::Plugin; +use zenoh_plugin_trait::PluginControl; +use zenoh_plugin_trait::PluginInstance; +use zenoh_protocol::core::key_expr::keyexpr; + zconfigurable! { pub static ref PLUGIN_PREFIX: String = "zenoh_plugin_".to_string(); } @@ -95,11 +103,3 @@ pub trait RunningPluginTrait: Send + Sync + PluginControl { /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. pub type PluginsManager = zenoh_plugin_trait::PluginsManager; - -use zenoh_plugin_trait::PluginCondition; -use zenoh_plugin_trait::PluginStatus; -pub use zenoh_plugin_trait::PluginStructVersion; -pub use zenoh_plugin_trait::Plugin; -use zenoh_plugin_trait::PluginControl; -use zenoh_plugin_trait::PluginInstance; -use zenoh_protocol::core::key_expr::keyexpr; From 11e573c3e4de2eae140253e93f3a711eb4c67d31 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 16 Nov 2023 13:21:22 +0100 Subject: [PATCH 050/106] debug error removed --- plugins/example-plugin/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 513a81bf4f..d9839cfeeb 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -48,7 +48,6 @@ impl Plugin for ExamplePlugin { // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { - bail!("Tra-ta-ta"); let config = runtime.config().lock(); let self_cfg = config.plugin(name).unwrap().as_object().unwrap(); // get the plugin's config details from self_cfg Map (here the "storage-selector" property) From 27c484112c258926797908092f2c3c53a648c144 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 17 Nov 2023 17:43:42 +0100 Subject: [PATCH 051/106] unfinished --- plugins/example-plugin/src/lib.rs | 2 +- plugins/example-storage-plugin/src/lib.rs | 8 +- plugins/zenoh-backend-traits/src/config.rs | 4 +- plugins/zenoh-backend-traits/src/lib.rs | 4 +- plugins/zenoh-plugin-rest/src/lib.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 8 +- .../src/memory_backend/mod.rs | 2 +- plugins/zenoh-plugin-trait/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/src/manager.rs | 3 + .../src/manager/dynamic_plugin.rs | 32 +++--- .../src/manager/static_plugin.rs | 7 +- plugins/zenoh-plugin-trait/src/plugin.rs | 105 +++++++++++++----- plugins/zenoh-plugin-trait/src/vtable.rs | 56 ++++++++-- zenoh/src/net/runtime/mod.rs | 4 +- zenoh/src/plugins/sealed.rs | 10 +- 15 files changed, 164 insertions(+), 85 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index d9839cfeeb..1babc8313f 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -44,7 +44,7 @@ impl Plugin for ExamplePlugin { type Instance = zenoh::plugins::RunningPlugin; // A mandatory const to define, in case of the plugin is built as a standalone executable - const STATIC_NAME: &'static str = "example"; + const DEFAULT_NAME: &'static str = "example"; // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index ef9c58d323..327ebc2c7e 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -38,13 +38,7 @@ impl Plugin for ExampleBackend { Ok(Box::new(volume)) } - const STATIC_NAME: &'static str = "example_backend"; -} - -#[no_mangle] -pub fn create_volume(_config: VolumeConfig) -> ZResult> { - let volume = ExampleBackend {}; - Ok(Box::new(volume)) + const DEFAULT_NAME: &'static str = "example_backend"; } pub struct ExampleBackend {} diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index 976b1e4846..fe089a23e5 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -70,10 +70,10 @@ pub struct ReplicaConfig { } impl PluginStructVersion for VolumeConfig { - fn version() -> u64 { + fn struct_version() -> u64 { 1 } - fn features() -> &'static str { + fn struct_features() -> &'static str { concatcp!(zenoh::FEATURES, crate::FEATURES) } } diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 6bb9f9c0a0..72d2e6f550 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -224,10 +224,10 @@ pub trait Volume: Send + Sync { pub type VolumePlugin = Box; impl PluginStructVersion for VolumePlugin { - fn version() -> u64 { + fn struct_version() -> u64 { 1 } - fn features() -> &'static str { + fn struct_features() -> &'static str { concatcp!(zenoh::FEATURES, crate::FEATURES) } } diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index eaaaef1887..65abfc3880 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -217,7 +217,7 @@ impl ZenohPlugin for RestPlugin {} impl Plugin for RestPlugin { type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; - const STATIC_NAME: &'static str = "rest"; + const DEFAULT_NAME: &'static str = "rest"; fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { // Try to initiate login. diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 3735e0ce1f..62d044f53c 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -23,7 +23,7 @@ use async_std::task; use flume::Sender; use memory_backend::MemoryBackend; use zenoh_plugin_trait::Plugin; -use zenoh_plugin_trait::PluginCondition; +use zenoh_plugin_trait::PluginReport; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginStatus; use std::collections::HashMap; @@ -59,7 +59,7 @@ zenoh_plugin_trait::declare_plugin!(StoragesPlugin); pub struct StoragesPlugin {} impl ZenohPlugin for StoragesPlugin {} impl Plugin for StoragesPlugin { - const STATIC_NAME: &'static str = "storage_manager"; + const DEFAULT_NAME: &'static str = "storage_manager"; type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; @@ -234,8 +234,8 @@ impl From for StorageRuntime { } impl PluginControl for StorageRuntime { - fn condition(&self) -> PluginCondition { - PluginCondition::default() + fn report(&self) -> PluginReport { + PluginReport::default() } fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { let guard = self.0.lock().unwrap(); diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index 2ebe534f84..0d990c5e65 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -32,7 +32,7 @@ impl Plugin for MemoryBackend { type StartArgs = VolumeConfig; type Instance = VolumePlugin; - const STATIC_NAME: &'static str = MEMORY_BACKEND_NAME; + const DEFAULT_NAME: &'static str = MEMORY_BACKEND_NAME; fn start(_: &str, args: &VolumeConfig) -> ZResult { Ok(Box::new(MemoryBackend { diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index bd3d1a7c15..0f9c3d57a9 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -25,7 +25,7 @@ mod vtable; pub use manager::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; pub use plugin::{ - Plugin, PluginCondition, PluginConditionSetter, PluginControl, PluginInfo, PluginInstance, + Plugin, PluginReport, PluginConditionSetter, PluginControl, PluginInfo, PluginInstance, PluginStartArgs, PluginState, PluginStatus, PluginStructVersion, }; pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index dd01b2cdb9..8f969ab0aa 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -56,6 +56,9 @@ impl PluginInfo fn name(&self) -> &str { self.0.name() } + fn plugin_version(&self) -> Option<&str> { + self.0.plugin_version() + } fn path(&self) -> &str { self.0.path() } diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index cfa0b25887..9b10a22b1c 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -11,9 +11,10 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::path::{PathBuf, Path}; +use std::{path::{PathBuf, Path}, borrow::Cow}; use libloading::Library; +use zenoh_keyexpr::keyexpr; use zenoh_result::{ZResult, bail}; use zenoh_util::LibLoader; @@ -49,13 +50,14 @@ impl DynamicPluginSource { struct DynamicPluginStarter { _lib: Library, path: PathBuf, + plugin_version: Cow<'static, keyexpr>, vtable: PluginVTable, } impl DynamicPluginStarter { - fn get_vtable(lib: &Library, path: &Path) -> ZResult> { + fn new(lib: Library, path: &Path) -> ZResult { log::debug!("Loading plugin {}", &path.to_str().unwrap(),); let get_plugin_loader_version = unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; @@ -70,7 +72,7 @@ impl } let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = Compatibility::new::(); + let host_compatibility_record = Compatibility::with_plugin_version_keyexpr::("**".try_into()? ); log::debug!( "Plugin compativilty record: {:?}", &plugin_compatibility_record @@ -85,13 +87,10 @@ impl let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); - Ok(vtable) - } - fn new(lib: Library, path: PathBuf) -> ZResult { - let vtable = Self::get_vtable(&lib, &path)?; Ok(Self { _lib: lib, - path, + path: path.to_path_buf(), + plugin_version: plugin_compatibility_record.plugin_version(), vtable, }) } @@ -105,7 +104,7 @@ impl pub struct DynamicPlugin { name: String, - condition: PluginCondition, + report: PluginReport, source: DynamicPluginSource, starter: Option>, instance: Option, @@ -115,7 +114,7 @@ impl DynamicPlugin { pub fn new(name: String, source: DynamicPluginSource) -> Self { Self { name, - condition: PluginCondition::new(), + report: PluginReport::new(), source, starter: None, instance: None, @@ -129,6 +128,9 @@ impl PluginInfo fn name(&self) -> &str { self.name.as_str() } + fn plugin_version(&self) -> Option<&str> { + self.starter.as_ref().map(|v| v.plugin_version) + } fn path(&self) -> &str { self.starter.as_ref().map_or("", |v| v.path()) } @@ -143,7 +145,7 @@ impl PluginInfo } else { PluginState::Declared }, - condition: self.condition.clone(), // TODO: request condition from started plugin + report: self.report.clone(), // TODO: request condition from started plugin } } } @@ -153,8 +155,8 @@ impl DeclaredPlugin ZResult<&mut dyn LoadedPlugin> { if self.starter.is_none() { - let (lib, path) = self.source.load().add_error(&mut self.condition)?; - let starter = DynamicPluginStarter::new(lib, path).add_error(&mut self.condition)?; + let (lib, path) = self.source.load().add_error(&mut self.report)?; + let starter = DynamicPluginStarter::new(lib, path).add_error(&mut self.report)?; log::debug!("Plugin {} loaded from {}", self.name, starter.path()); self.starter = Some(starter); } else { @@ -186,12 +188,12 @@ impl LoadedPlugin, { fn name(&self) -> &str { - P::STATIC_NAME + P::DEFAULT_NAME + } + fn plugin_version(&self) -> Option<&str> { + Some(P::PLUGIN_VERSION) } fn path(&self) -> &str { "" @@ -51,7 +54,7 @@ where .instance .as_ref() .map_or(PluginState::Loaded, |_| PluginState::Started), - condition: PluginCondition::new(), // TODO: request runnnig plugin status + report: PluginReport::new(), // TODO: request runnnig plugin status } } } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 534ebab794..9991dfb121 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -11,41 +11,69 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::borrow::Cow; +use serde::{Deserialize, Serialize}; +use std::{borrow::Cow, ops::BitOrAssign}; use zenoh_keyexpr::keyexpr; use zenoh_result::ZResult; -use serde::{Deserialize, Serialize}; -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +/// The plugin can be in one of these states: +/// - Declared: the plugin is declared in the configuration file, but not loaded yet or failed to load +/// - Loaded: the plugin is loaded, but not started yet or failed to start +/// - Started: the plugin is started and running +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] pub enum PluginState { Declared, Loaded, Started, } +/// The severity level of a plugin report messages +/// - Normal: the message(s) is just a notification +/// - Warning: at least one warning is reported +/// - Error: at least one error is reported +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, PartialOrd, Ord)] +pub enum PluginReportLevel { + #[default] + Normal, + Warning, + Error, +} + +/// Allow to use `|=` operator to update the severity level of a report +impl BitOrAssign for PluginReportLevel { + fn bitor_assign(&mut self, rhs: Self) { + if *self < rhs { + *self = rhs; + } + } +} + +/// A plugin report contains a severity level and a list of messages #[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] -pub struct PluginCondition { - #[serde(skip_serializing_if = "Vec::is_empty")] - warnings: Vec>, +pub struct PluginReport { + level: PluginReportLevel, #[serde(skip_serializing_if = "Vec::is_empty")] - errors: Vec>, + messages: Vec>, } +/// The status of a plugin contains the plugin state (Declared, Loaded, Started) and a report +/// describing the plugin's situation (for Declared state - dynamic library loading errors, for Loaded state - plugin start errors, etc) #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PluginStatus { pub state: PluginState, - pub condition: PluginCondition, + pub report: PluginReport, } pub trait PluginInfo { fn name(&self) -> &str; + fn plugin_version(&self) -> Option<&str>; fn path(&self) -> &str; fn status(&self) -> PluginStatus; } pub trait PluginControl { - fn condition(&self) -> PluginCondition { - PluginCondition::default() + fn report(&self) -> PluginReport { + PluginReport::default() } /// Collect information of sub-plugins matching `_names` keyexpr fn plugins_status(&self, _names: &keyexpr) -> Vec<(String, PluginStatus)> { @@ -56,11 +84,11 @@ pub trait PluginControl { pub trait PluginStructVersion { /// The version of the structure implementing this trait. After any channge in the structure or it's dependencies /// whcich may affect the ABI, this version should be incremented. - fn version() -> u64; - /// The features enabled during comiplation of the structure implementing this trait. + fn struct_version() -> u64; + /// The features enabled during compilation of the structure implementing this trait. /// Different features between the plugin and the host may cuase ABI incompatibility even if the structure version is the same. /// Use `concat_enabled_features!` to generate this string - fn features() -> &'static str; + fn struct_features() -> &'static str; } pub trait PluginStartArgs: PluginStructVersion {} @@ -70,49 +98,66 @@ pub trait PluginInstance: PluginStructVersion + PluginControl + Send {} pub trait Plugin: Sized + 'static { type StartArgs: PluginStartArgs; type Instance: PluginInstance; - /// Your plugins' default name when statically linked. - const STATIC_NAME: &'static str; + /// Plugins' default name when statically linked. + const DEFAULT_NAME: &'static str; + /// Plugin's version. Defined as `keyexpr` to allow advanced plugin version validation. + /// At this moment this feature is not used: plugin mamager always matches plugin's version with "**". + /// But in the future it may be used to allow zenohd to load plugins with compatible versions only, accordingly + /// to requested version range in the configuration file. + const PLUGIN_VERSION: &'static keyexpr; /// Starts your plugin. Use `Ok` to return your plugin's control structure fn start(name: &str, args: &Self::StartArgs) -> ZResult; } -impl PluginCondition { +impl PluginReport { pub fn new() -> Self { Self::default() } pub fn clear(&mut self) { - self.warnings.clear(); - self.errors.clear(); + *self = Self::default(); + } + pub fn get_level(&self) -> PluginReportLevel { + self.level } pub fn add_error>>(&mut self, error: S) { - self.errors.push(error.into()); + self.level |= PluginReportLevel::Error; + self.messages.push(error.into()); } pub fn add_warning>>(&mut self, warning: S) { - self.warnings.push(warning.into()); + self.level |= PluginReportLevel::Warning; + self.messages.push(warning.into()); } - pub fn errors(&self) -> &[Cow<'static, str>] { - &self.errors + pub fn add_message>>(&mut self, message: S) { + self.level |= PluginReportLevel::Normal; + self.messages.push(message.into()); } - pub fn warnings(&self) -> &[Cow<'static, str>] { - &self.warnings + pub fn messages(&self) -> &[Cow<'static, str>] { + &self.messages } } pub trait PluginConditionSetter { - fn add_error(self, condition: &mut PluginCondition) -> Self; - fn add_warning(self, condition: &mut PluginCondition) -> Self; + fn add_error(self, report: &mut PluginReport) -> Self; + fn add_warning(self, report: &mut PluginReport) -> Self; + fn add_message(self, report: &mut PluginReport) -> Self; } impl PluginConditionSetter for core::result::Result { - fn add_error(self, condition: &mut PluginCondition) -> Self { + fn add_error(self, report: &mut PluginReport) -> Self { + if let Err(e) = &self { + report.add_error(e.to_string()); + } + self + } + fn add_warning(self, report: &mut PluginReport) -> Self { if let Err(e) = &self { - condition.add_error(e.to_string()); + report.add_warning(e.to_string()); } self } - fn add_warning(self, condition: &mut PluginCondition) -> Self { + fn add_message(self, report: &mut PluginReport) -> Self { if let Err(e) = &self { - condition.add_warning(e.to_string()); + report.add_message(e.to_string()); } self } diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index ec863d73ca..50f5611742 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -1,4 +1,3 @@ - // // Copyright (c) 2023 ZettaScale Technology // @@ -13,8 +12,9 @@ // ZettaScale Zenoh Team, // use crate::*; +use std::{borrow::Cow, fmt::Display}; +use zenoh_keyexpr::keyexpr; use zenoh_result::ZResult; -use std::fmt::Display; pub type PluginLoaderVersion = u64; pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; @@ -26,10 +26,10 @@ pub struct PluginVTable { pub start: StartFn, } impl PluginStructVersion for PluginVTable { - fn version() -> u64 { + fn struct_version() -> u64 { 1 } - fn features() -> &'static str { + fn struct_features() -> &'static str { FEATURES } } @@ -45,9 +45,9 @@ pub struct StructVersion { impl StructVersion { pub fn new() -> Self { Self { - version: T::version(), + version: T::struct_version(), name: std::any::type_name::(), - features: T::features(), + features: T::struct_features(), } } } @@ -69,26 +69,57 @@ pub struct Compatibility { vtable_version: StructVersion, start_args_version: StructVersion, instance_version: StructVersion, + plugin_version: Cow<'static, keyexpr>, } impl Compatibility { - pub fn new() -> Self { + pub fn new< + StartArgsType: PluginStartArgs, + InstanceType: PluginInstance, + PluginType: Plugin, + >() -> Self { + let rust_version = RustVersion::new(); + let vtable_version = StructVersion::new::>(); + let start_args_version = StructVersion::new::(); + let instance_version = StructVersion::new::(); + let plugin_version = Cow::Borrowed(PluginType::PLUGIN_VERSION); + Self { + rust_version, + vtable_version, + start_args_version, + instance_version, + plugin_version, + } + } + pub fn with_plugin_version_keyexpr< + StartArgsType: PluginStartArgs, + InstanceType: PluginInstance, + >( + plugin_version: Cow<'static, keyexpr>, + ) -> Self { let rust_version = RustVersion::new(); - let vtable_version = StructVersion::new::>(); - let start_args_version = StructVersion::new::(); - let instance_version = StructVersion::new::(); + let vtable_version = StructVersion::new::>(); + let start_args_version = StructVersion::new::(); + let instance_version = StructVersion::new::(); Self { rust_version, vtable_version, start_args_version, instance_version, + plugin_version, } } + pub fn plugin_version(&self) -> Cow<'static, keyexpr> { + self.plugin_version + } pub fn are_compatible(&self, other: &Self) -> bool { RustVersion::are_compatible(&self.rust_version, &other.rust_version) && self.vtable_version == other.vtable_version && self.start_args_version == other.start_args_version && self.instance_version == other.instance_version + && self + .plugin_version + .intersects(other.plugin_version.as_ref()) } } @@ -96,11 +127,12 @@ impl Display for Compatibility { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "{}\nVTable:{}StartArgs:{}Instance:{}", + "{}\nVTable:{}StartArgs:{}Instance:{}Plugin:{}", self.rust_version, self.vtable_version, self.start_args_version, - self.instance_version + self.instance_version, + self.plugin_version ) } } diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 054a7421d0..912b2a298f 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -66,10 +66,10 @@ pub struct Runtime { } impl PluginStructVersion for Runtime { - fn version() -> u64 { + fn struct_version() -> u64 { 1 } - fn features() -> &'static str { + fn struct_features() -> &'static str { crate::FEATURES } } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index e823357646..1f1e8ac69b 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -19,7 +19,7 @@ pub use crate::runtime::Runtime; pub use crate::Result as ZResult; use zenoh_core::zconfigurable; -use zenoh_plugin_trait::PluginCondition; +use zenoh_plugin_trait::PluginReport; use zenoh_plugin_trait::PluginStatus; use zenoh_plugin_trait::PluginStructVersion; use zenoh_plugin_trait::Plugin; @@ -40,17 +40,17 @@ pub type StartArgs = Runtime; pub type RunningPlugin = Box; impl PluginStructVersion for RunningPlugin { - fn version() -> u64 { + fn struct_version() -> u64 { 1 } - fn features() -> &'static str { + fn struct_features() -> &'static str { crate::FEATURES } } impl PluginControl for RunningPlugin { - fn condition(&self) -> PluginCondition { - self.as_ref().condition() + fn report(&self) -> PluginReport { + self.as_ref().report() } fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { From 52e0ea53b3b2980d86745e091966b61d5b9b2928 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 18 Nov 2023 23:39:02 +0100 Subject: [PATCH 052/106] plugin version in compatibility api --- plugins/example-plugin/src/lib.rs | 5 +-- plugins/example-storage-plugin/src/lib.rs | 2 +- plugins/zenoh-plugin-rest/src/lib.rs | 3 +- .../zenoh-plugin-storage-manager/src/lib.rs | 36 ++++++++++++------- .../src/memory_backend/mod.rs | 1 + plugins/zenoh-plugin-trait/Cargo.toml | 3 +- .../src/manager/dynamic_plugin.rs | 19 +++++----- plugins/zenoh-plugin-trait/src/plugin.rs | 8 ++--- plugins/zenoh-plugin-trait/src/vtable.rs | 28 +++++++-------- 9 files changed, 57 insertions(+), 48 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 1babc8313f..1a00e98e08 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -15,17 +15,17 @@ use futures::select; use log::{debug, info}; -use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::{ atomic::{AtomicBool, Ordering::Relaxed}, Arc, Mutex, }; +use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; -use zenoh_plugin_trait::{PluginControl, Plugin}; +use zenoh_plugin_trait::{Plugin, PluginControl}; use zenoh_result::{bail, ZResult}; // The struct implementing the ZenohPlugin and ZenohPlugin traits @@ -45,6 +45,7 @@ impl Plugin for ExamplePlugin { // A mandatory const to define, in case of the plugin is built as a standalone executable const DEFAULT_NAME: &'static str = "example"; + const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index 327ebc2c7e..fac7fbf295 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -32,13 +32,13 @@ zenoh_plugin_trait::declare_plugin!(ExampleBackend); impl Plugin for ExampleBackend { type StartArgs = VolumeConfig; type Instance = VolumePlugin; - fn start(_name: &str, _args: &Self::StartArgs) -> ZResult { let volume = ExampleBackend {}; Ok(Box::new(volume)) } const DEFAULT_NAME: &'static str = "example_backend"; + const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); } pub struct ExampleBackend {} diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 65abfc3880..fb9fb17b49 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -21,7 +21,6 @@ use async_std::prelude::FutureExt; use base64::{engine::general_purpose::STANDARD as b64_std_engine, Engine}; use futures::StreamExt; use http_types::Method; -use zenoh_plugin_trait::{PluginControl, Plugin}; use std::convert::TryFrom; use std::str::FromStr; use std::sync::Arc; @@ -35,6 +34,7 @@ use zenoh::query::{QueryConsolidation, Reply}; use zenoh::runtime::Runtime; use zenoh::selector::TIME_RANGE_KEY; use zenoh::Session; +use zenoh_plugin_trait::{Plugin, PluginControl}; use zenoh_result::{bail, zerror, ZResult}; mod config; @@ -218,6 +218,7 @@ impl Plugin for RestPlugin { type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; const DEFAULT_NAME: &'static str = "rest"; + const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { // Try to initiate login. diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 62d044f53c..d5db7fa074 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -22,10 +22,6 @@ use async_std::task; use flume::Sender; use memory_backend::MemoryBackend; -use zenoh_plugin_trait::Plugin; -use zenoh_plugin_trait::PluginReport; -use zenoh_plugin_trait::PluginControl; -use zenoh_plugin_trait::PluginStatus; use std::collections::HashMap; use std::convert::TryFrom; use std::sync::Arc; @@ -41,6 +37,10 @@ use zenoh_backend_traits::config::StorageConfig; use zenoh_backend_traits::config::VolumeConfig; use zenoh_backend_traits::VolumePlugin; use zenoh_core::zlock; +use zenoh_plugin_trait::Plugin; +use zenoh_plugin_trait::PluginControl; +use zenoh_plugin_trait::PluginReport; +use zenoh_plugin_trait::PluginStatus; use zenoh_result::ZResult; use zenoh_util::LibLoader; @@ -60,6 +60,7 @@ pub struct StoragesPlugin {} impl ZenohPlugin for StoragesPlugin {} impl Plugin for StoragesPlugin { const DEFAULT_NAME: &'static str = "storage_manager"; + const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; @@ -160,20 +161,25 @@ impl StorageRuntimeInner { .map(|s| async move { s.send(StorageMessage::Stop) }), )); } - self.plugins_manager.started_plugin_mut(name).ok_or(format!( - "Cannot find volume {} to stop it", - name - ))?.stop(); + self.plugins_manager + .started_plugin_mut(name) + .ok_or(format!("Cannot find volume {} to stop it", name))? + .stop(); Ok(()) } fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); - log::info!("Spawning volume {} with backend {}", volume_id, backend_name); + log::info!( + "Spawning volume {} with backend {}", + volume_id, + backend_name + ); let declared = if let Some(declared) = self.plugins_manager.plugin_mut(volume_id) { declared } else if let Some(paths) = config.paths() { - self.plugins_manager.declare_dynamic_plugin_by_paths(volume_id, paths)? + self.plugins_manager + .declare_dynamic_plugin_by_paths(volume_id, paths)? } else { self.plugins_manager .declare_dynamic_plugin_by_name(volume_id, backend_name)? @@ -200,9 +206,13 @@ impl StorageRuntimeInner { fn spawn_storage(&mut self, storage: StorageConfig) -> ZResult<()> { let admin_key = self.status_key() + "/storages/" + &storage.name; let volume_id = storage.volume_id.clone(); - let backend = self.plugins_manager.started_plugin(&volume_id).ok_or( - format!("Cannot find volume {} to spawn storage {}", volume_id, storage.name), - )?; + let backend = self + .plugins_manager + .started_plugin(&volume_id) + .ok_or(format!( + "Cannot find volume {} to spawn storage {}", + volume_id, storage.name + ))?; let storage_name = storage.name.clone(); log::info!( "Spawning storage {} from volume {} with backend {}", diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index 0d990c5e65..c9d0509554 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -33,6 +33,7 @@ impl Plugin for MemoryBackend { type Instance = VolumePlugin; const DEFAULT_NAME: &'static str = MEMORY_BACKEND_NAME; + const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); fn start(_: &str, args: &VolumeConfig) -> ZResult { Ok(Box::new(MemoryBackend { diff --git a/plugins/zenoh-plugin-trait/Cargo.toml b/plugins/zenoh-plugin-trait/Cargo.toml index 679feba9a1..ebae9efea5 100644 --- a/plugins/zenoh-plugin-trait/Cargo.toml +++ b/plugins/zenoh-plugin-trait/Cargo.toml @@ -39,4 +39,5 @@ zenoh-macros = { workspace = true } zenoh-result = { workspace = true } zenoh-util = { workspace = true } zenoh-keyexpr = { workspace = true } -const_format = { workspace = true } \ No newline at end of file +const_format = { workspace = true } +version-compare = { workspace = true } \ No newline at end of file diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index 9b10a22b1c..9fcbaacc41 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -11,14 +11,12 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::{path::{PathBuf, Path}, borrow::Cow}; +use std::path::PathBuf; use libloading::Library; -use zenoh_keyexpr::keyexpr; -use zenoh_result::{ZResult, bail}; +use zenoh_result::{bail, ZResult}; use zenoh_util::LibLoader; - /// This enum contains information where to load the plugin from. pub enum DynamicPluginSource { /// Load plugin with the name in String + `.so | .dll | .dylib` @@ -50,14 +48,14 @@ impl DynamicPluginSource { struct DynamicPluginStarter { _lib: Library, path: PathBuf, - plugin_version: Cow<'static, keyexpr>, + plugin_version: &'static str, vtable: PluginVTable, } impl DynamicPluginStarter { - fn new(lib: Library, path: &Path) -> ZResult { + fn new(lib: Library, path: PathBuf) -> ZResult { log::debug!("Loading plugin {}", &path.to_str().unwrap(),); let get_plugin_loader_version = unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; @@ -72,7 +70,8 @@ impl } let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = Compatibility::with_plugin_version_keyexpr::("**".try_into()? ); + let host_compatibility_record = + Compatibility::with_empty_plugin_version::(); log::debug!( "Plugin compativilty record: {:?}", &plugin_compatibility_record @@ -87,10 +86,11 @@ impl let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); + let plugin_version = plugin_compatibility_record.plugin_version(); Ok(Self { _lib: lib, - path: path.to_path_buf(), - plugin_version: plugin_compatibility_record.plugin_version(), + path, + plugin_version, vtable, }) } @@ -231,4 +231,3 @@ impl StartedPlugin, level: PluginReportLevel, #[serde(skip_serializing_if = "Vec::is_empty")] messages: Vec>, @@ -100,11 +101,8 @@ pub trait Plugin: Sized + 'static { type Instance: PluginInstance; /// Plugins' default name when statically linked. const DEFAULT_NAME: &'static str; - /// Plugin's version. Defined as `keyexpr` to allow advanced plugin version validation. - /// At this moment this feature is not used: plugin mamager always matches plugin's version with "**". - /// But in the future it may be used to allow zenohd to load plugins with compatible versions only, accordingly - /// to requested version range in the configuration file. - const PLUGIN_VERSION: &'static keyexpr; + /// Plugin's version. Used only for information purposes. + const PLUGIN_VERSION: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure fn start(name: &str, args: &Self::StartArgs) -> ZResult; } diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 50f5611742..ce6bf32193 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -12,8 +12,7 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::{borrow::Cow, fmt::Display}; -use zenoh_keyexpr::keyexpr; +use std::fmt::Display; use zenoh_result::ZResult; pub type PluginLoaderVersion = u64; @@ -69,11 +68,11 @@ pub struct Compatibility { vtable_version: StructVersion, start_args_version: StructVersion, instance_version: StructVersion, - plugin_version: Cow<'static, keyexpr>, + plugin_version: &'static str, } impl Compatibility { - pub fn new< + pub fn with_plugin_version< StartArgsType: PluginStartArgs, InstanceType: PluginInstance, PluginType: Plugin, @@ -82,7 +81,7 @@ impl Compatibility { let vtable_version = StructVersion::new::>(); let start_args_version = StructVersion::new::(); let instance_version = StructVersion::new::(); - let plugin_version = Cow::Borrowed(PluginType::PLUGIN_VERSION); + let plugin_version = PluginType::PLUGIN_VERSION; Self { rust_version, vtable_version, @@ -91,12 +90,10 @@ impl Compatibility { plugin_version, } } - pub fn with_plugin_version_keyexpr< + pub fn with_empty_plugin_version< StartArgsType: PluginStartArgs, InstanceType: PluginInstance, - >( - plugin_version: Cow<'static, keyexpr>, - ) -> Self { + >() -> Self { let rust_version = RustVersion::new(); let vtable_version = StructVersion::new::>(); let start_args_version = StructVersion::new::(); @@ -106,20 +103,20 @@ impl Compatibility { vtable_version, start_args_version, instance_version, - plugin_version, + plugin_version: "", } } - pub fn plugin_version(&self) -> Cow<'static, keyexpr> { + pub fn plugin_version(&self) -> &'static str { self.plugin_version } + /// Returns true if rust compiler and structures version are exactly the same and + /// plugin version is compatible with the requested version range in the configuration file pub fn are_compatible(&self, other: &Self) -> bool { RustVersion::are_compatible(&self.rust_version, &other.rust_version) && self.vtable_version == other.vtable_version && self.start_args_version == other.start_args_version && self.instance_version == other.instance_version - && self - .plugin_version - .intersects(other.plugin_version.as_ref()) + // TODO: check plugin version may be added later } } @@ -216,9 +213,10 @@ pub mod no_mangle { #[no_mangle] fn get_compatibility() -> $crate::Compatibility { - $crate::Compatibility::new::< + $crate::Compatibility::with_plugin_version::< <$ty as $crate::Plugin>::StartArgs, <$ty as $crate::Plugin>::Instance, + $ty, >() } From e1b5ed5262c9a3a008cca4b158ce761028b8ef4a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 19 Nov 2023 00:51:32 +0100 Subject: [PATCH 053/106] version in plugin status unfinished --- plugins/zenoh-plugin-trait/Cargo.toml | 3 +- plugins/zenoh-plugin-trait/src/manager.rs | 32 +++++++++++-------- .../src/manager/dynamic_plugin.rs | 22 +++++++------ .../src/manager/static_plugin.rs | 28 ++++++++-------- plugins/zenoh-plugin-trait/src/plugin.rs | 9 +++--- 5 files changed, 50 insertions(+), 44 deletions(-) diff --git a/plugins/zenoh-plugin-trait/Cargo.toml b/plugins/zenoh-plugin-trait/Cargo.toml index ebae9efea5..362ae942d6 100644 --- a/plugins/zenoh-plugin-trait/Cargo.toml +++ b/plugins/zenoh-plugin-trait/Cargo.toml @@ -39,5 +39,4 @@ zenoh-macros = { workspace = true } zenoh-result = { workspace = true } zenoh-util = { workspace = true } zenoh-keyexpr = { workspace = true } -const_format = { workspace = true } -version-compare = { workspace = true } \ No newline at end of file +const_format = { workspace = true } \ No newline at end of file diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index 8f969ab0aa..b94bc9e6aa 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -56,12 +56,6 @@ impl PluginInfo fn name(&self) -> &str { self.0.name() } - fn plugin_version(&self) -> Option<&str> { - self.0.plugin_version() - } - fn path(&self) -> &str { - self.0.path() - } fn status(&self) -> PluginStatus { self.0.status() } @@ -117,7 +111,10 @@ impl ) -> Self { let plugin_loader: StaticPlugin = StaticPlugin::new(); self.plugins.push(PluginRecord::new(plugin_loader)); - log::debug!("Declared static plugin {}", self.plugins.last().unwrap().name()); + log::debug!( + "Declared static plugin {}", + self.plugins.last().unwrap().name() + ); self } @@ -135,10 +132,8 @@ impl .ok_or("Dynamic plugin loading is disabled")? .clone(); log::debug!("Declared dynamic plugin {} by name {}", &name, &plugin_name); - let loader = DynamicPlugin::new( - name, - DynamicPluginSource::ByName((libloader, plugin_name)), - ); + let loader = + DynamicPlugin::new(name, DynamicPluginSource::ByName((libloader, plugin_name))); self.plugins.push(PluginRecord::new(loader)); Ok(self.plugins.last_mut().unwrap()) } @@ -254,7 +249,11 @@ impl P for PluginsManager { fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { - log::debug!("Plugin manager with prefix `{}` : requested plugins_status {:?}", self.default_lib_prefix , names); + log::debug!( + "Plugin manager with prefix `{}` : requested plugins_status {:?}", + self.default_lib_prefix, + names + ); let mut plugins = Vec::new(); for plugin in self.declared_plugins() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; @@ -265,7 +264,14 @@ impl P if let Some(plugin) = plugin.loaded() { if let Some(plugin) = plugin.started() { if let [names, ..] = names.strip_prefix(name)[..] { - plugins.append(&mut plugin.instance().plugins_status(names).iter().map(|(n, s)| (format!("{}/{}", name, n), s.clone())).collect()); + plugins.append( + &mut plugin + .instance() + .plugins_status(names) + .iter() + .map(|(n, s)| (format!("{}/{}", name, n), s.clone())) + .collect(), + ); } } } diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index 9fcbaacc41..44da50115f 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -11,7 +11,7 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::path::PathBuf; +use std::{borrow::Cow, path::PathBuf}; use libloading::Library; use zenoh_result::{bail, ZResult}; @@ -86,11 +86,10 @@ impl let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; let vtable = load_plugin(); - let plugin_version = plugin_compatibility_record.plugin_version(); Ok(Self { _lib: lib, path, - plugin_version, + plugin_version: plugin_compatibility_record.plugin_version(), vtable, }) } @@ -128,14 +127,13 @@ impl PluginInfo fn name(&self) -> &str { self.name.as_str() } - fn plugin_version(&self) -> Option<&str> { - self.starter.as_ref().map(|v| v.plugin_version) - } - fn path(&self) -> &str { - self.starter.as_ref().map_or("", |v| v.path()) - } fn status(&self) -> PluginStatus { PluginStatus { + version: self + .starter + .as_ref() + .map(|v| Cow::Borrowed(v.plugin_version)), + path: self.starter.as_ref().map(|v| Cow::Borrowed(v.path())), state: if self.starter.is_some() { if self.instance.is_some() { PluginState::Started @@ -145,7 +143,11 @@ impl PluginInfo } else { PluginState::Declared }, - report: self.report.clone(), // TODO: request condition from started plugin + report: if let Some(instance) = &self.instance { + instance.report() + } else { + self.report.clone() + }, } } } diff --git a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs index 673d03e812..231cc7f803 100644 --- a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs @@ -12,10 +12,10 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::marker::PhantomData; +use std::{borrow::Cow, marker::PhantomData}; use zenoh_result::ZResult; -pub struct StaticPlugin +pub struct StaticPlugin where P: Plugin, { @@ -23,7 +23,7 @@ where phantom: PhantomData

, } -impl StaticPlugin +impl StaticPlugin where P: Plugin, { @@ -35,31 +35,31 @@ where } } -impl PluginInfo for StaticPlugin +impl PluginInfo for StaticPlugin where P: Plugin, { fn name(&self) -> &str { P::DEFAULT_NAME } - fn plugin_version(&self) -> Option<&str> { - Some(P::PLUGIN_VERSION) - } - fn path(&self) -> &str { - "" - } fn status(&self) -> PluginStatus { PluginStatus { + version: Some(Cow::Borrowed(P::PLUGIN_VERSION)), + path: None, state: self .instance .as_ref() .map_or(PluginState::Loaded, |_| PluginState::Started), - report: PluginReport::new(), // TODO: request runnnig plugin status + report: if let Some(instance) = &self.instance { + instance.report() + } else { + PluginReport::default() + }, } } } -impl DeclaredPlugin +impl DeclaredPlugin for StaticPlugin where P: Plugin, @@ -75,7 +75,7 @@ where } } -impl LoadedPlugin +impl LoadedPlugin for StaticPlugin where P: Plugin, @@ -105,7 +105,7 @@ where } } -impl StartedPlugin +impl StartedPlugin for StaticPlugin where P: Plugin, diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 6b72a74c8b..22919cef8a 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -49,9 +49,8 @@ impl BitOrAssign for PluginReportLevel { } /// A plugin report contains a severity level and a list of messages -#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Default, Deserialize)] pub struct PluginReport { - version: Cow<'static, str>, level: PluginReportLevel, #[serde(skip_serializing_if = "Vec::is_empty")] messages: Vec>, @@ -60,15 +59,15 @@ pub struct PluginReport { /// The status of a plugin contains the plugin state (Declared, Loaded, Started) and a report /// describing the plugin's situation (for Declared state - dynamic library loading errors, for Loaded state - plugin start errors, etc) #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct PluginStatus { +pub struct PluginStatus<'a> { + pub version: Option>, + pub path: Option>, pub state: PluginState, pub report: PluginReport, } pub trait PluginInfo { fn name(&self) -> &str; - fn plugin_version(&self) -> Option<&str>; - fn path(&self) -> &str; fn status(&self) -> PluginStatus; } From d1b4af8e4160307757b240eb66c9375905cfe109 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 19 Nov 2023 13:35:16 +0100 Subject: [PATCH 054/106] version works --- plugins/zenoh-backend-traits/src/lib.rs | 4 +- .../zenoh-plugin-storage-manager/src/lib.rs | 7 ++- plugins/zenoh-plugin-trait/src/lib.rs | 4 +- plugins/zenoh-plugin-trait/src/manager.rs | 22 ++++++-- .../src/manager/dynamic_plugin.rs | 51 +++++++++++-------- .../src/manager/static_plugin.rs | 34 +++++++------ plugins/zenoh-plugin-trait/src/plugin.rs | 43 ++++++++++++++-- zenoh/src/net/runtime/adminspace.rs | 8 +-- zenoh/src/plugins/sealed.rs | 6 +-- 9 files changed, 118 insertions(+), 61 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 72d2e6f550..5d4e100a66 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -139,7 +139,9 @@ use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; -use zenoh_plugin_trait::{concat_enabled_features, PluginStructVersion, PluginControl, PluginInstance, PluginStatus}; +use zenoh_plugin_trait::{ + concat_enabled_features, PluginControl, PluginInstance, PluginStatus, PluginStructVersion, +}; pub mod config; use config::{StorageConfig, VolumeConfig}; diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index d5db7fa074..46be81a4be 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -249,7 +249,12 @@ impl PluginControl for StorageRuntime { } fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { let guard = self.0.lock().unwrap(); - guard.plugins_manager.plugins_status(names) + guard + .plugins_manager + .plugins_status(names) + .into_iter() + .map(|(k, v)| (k, v.into_owned())) + .collect() } } diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 0f9c3d57a9..856689df9b 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -25,8 +25,8 @@ mod vtable; pub use manager::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; pub use plugin::{ - Plugin, PluginReport, PluginConditionSetter, PluginControl, PluginInfo, PluginInstance, - PluginStartArgs, PluginState, PluginStatus, PluginStructVersion, + Plugin, PluginConditionSetter, PluginControl, PluginInstance, PluginReport, PluginStartArgs, + PluginState, PluginStatus, PluginStatusGetter, PluginStructVersion, }; pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index b94bc9e6aa..ae7daad689 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -23,18 +23,18 @@ use self::{ static_plugin::StaticPlugin, }; -pub trait DeclaredPlugin: PluginInfo { +pub trait DeclaredPlugin: PluginStatusGetter { fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin>; fn loaded(&self) -> Option<&dyn LoadedPlugin>; fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin>; } -pub trait LoadedPlugin: PluginInfo { +pub trait LoadedPlugin: PluginStatusGetter { fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin>; fn started(&self) -> Option<&dyn StartedPlugin>; fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin>; } -pub trait StartedPlugin: PluginInfo { +pub trait StartedPlugin: PluginStatusGetter { fn stop(&mut self); fn instance(&self) -> &Instance; fn instance_mut(&mut self) -> &mut Instance; @@ -50,12 +50,24 @@ impl PluginRecord PluginInfo +impl PluginStatusGetter for PluginRecord { fn name(&self) -> &str { self.0.name() } + fn version(&self) -> Option<&str> { + self.0.version() + } + fn path(&self) -> &str { + self.0.path() + } + fn state(&self) -> PluginState { + self.0.state() + } + fn report(&self) -> PluginReport { + self.0.report() + } fn status(&self) -> PluginStatus { self.0.status() } @@ -254,7 +266,7 @@ impl P self.default_lib_prefix, names ); - let mut plugins = Vec::new(); + let mut plugins: Vec<(String, PluginStatus)> = Vec::new(); for plugin in self.declared_plugins() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; if names.includes(name) { diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index 44da50115f..d4842e1e0d 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -11,7 +11,7 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::{borrow::Cow, path::PathBuf}; +use std::path::PathBuf; use libloading::Library; use zenoh_result::{bail, ZResult}; @@ -121,33 +121,39 @@ impl DynamicPlugin { } } -impl PluginInfo +impl PluginStatusGetter for DynamicPlugin { fn name(&self) -> &str { self.name.as_str() } - fn status(&self) -> PluginStatus { - PluginStatus { - version: self - .starter - .as_ref() - .map(|v| Cow::Borrowed(v.plugin_version)), - path: self.starter.as_ref().map(|v| Cow::Borrowed(v.path())), - state: if self.starter.is_some() { - if self.instance.is_some() { - PluginState::Started - } else { - PluginState::Loaded - } - } else { - PluginState::Declared - }, - report: if let Some(instance) = &self.instance { - instance.report() + fn version(&self) -> Option<&str> { + self.starter.as_ref().map(|v| v.plugin_version) + } + + fn path(&self) -> &str { + if let Some(starter) = &self.starter { + starter.path() + } else { + "" + } + } + fn state(&self) -> PluginState { + if self.starter.is_some() { + if self.instance.is_some() { + PluginState::Started } else { - self.report.clone() - }, + PluginState::Loaded + } + } else { + PluginState::Declared + } + } + fn report(&self) -> PluginReport { + if let Some(instance) = &self.instance { + instance.report() + } else { + self.report.clone() } } } @@ -224,6 +230,7 @@ impl StartedPlugin &Instance { diff --git a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs index 231cc7f803..1eb440bac8 100644 --- a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::{borrow::Cow, marker::PhantomData}; +use std::marker::PhantomData; use zenoh_result::ZResult; pub struct StaticPlugin @@ -35,26 +35,30 @@ where } } -impl PluginInfo for StaticPlugin +impl PluginStatusGetter + for StaticPlugin where P: Plugin, { fn name(&self) -> &str { P::DEFAULT_NAME } - fn status(&self) -> PluginStatus { - PluginStatus { - version: Some(Cow::Borrowed(P::PLUGIN_VERSION)), - path: None, - state: self - .instance - .as_ref() - .map_or(PluginState::Loaded, |_| PluginState::Started), - report: if let Some(instance) = &self.instance { - instance.report() - } else { - PluginReport::default() - }, + fn version(&self) -> Option<&str> { + Some(P::PLUGIN_VERSION) + } + fn path(&self) -> &str { + "" + } + fn state(&self) -> PluginState { + self.instance + .as_ref() + .map_or(PluginState::Loaded, |_| PluginState::Started) + } + fn report(&self) -> PluginReport { + if let Some(instance) = &self.instance { + instance.report() + } else { + PluginReport::default() } } } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 22919cef8a..69c25f9b10 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -49,6 +49,7 @@ impl BitOrAssign for PluginReportLevel { } /// A plugin report contains a severity level and a list of messages +/// describing the plugin's situation (for Declared state - dynamic library loading errors, for Loaded state - plugin start errors, etc) #[derive(Clone, Debug, PartialEq, Eq, Serialize, Default, Deserialize)] pub struct PluginReport { level: PluginReportLevel, @@ -56,19 +57,51 @@ pub struct PluginReport { messages: Vec>, } -/// The status of a plugin contains the plugin state (Declared, Loaded, Started) and a report -/// describing the plugin's situation (for Declared state - dynamic library loading errors, for Loaded state - plugin start errors, etc) +/// The status of a plugin contains all information about the plugin in single cloneable structure #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PluginStatus<'a> { + pub name: Cow<'a, str>, + #[serde(skip_serializing_if = "Option::is_none")] pub version: Option>, - pub path: Option>, + pub path: Cow<'a, str>, pub state: PluginState, pub report: PluginReport, } -pub trait PluginInfo { +impl PluginStatus<'_> { + pub fn into_owned(self) -> PluginStatus<'static> { + PluginStatus { + name: Cow::Owned(self.name.into_owned()), + version: self.version.map(|v| Cow::Owned(v.into_owned())), + path: Cow::Owned(self.path.into_owned()), + state: self.state, + report: self.report, + } + } +} + +pub trait PluginStatusGetter { + /// Returns name of the plugin fn name(&self) -> &str; - fn status(&self) -> PluginStatus; + /// Returns version of the loaded plugin (usually the version of the plugin's crate) + fn version(&self) -> Option<&str>; + /// Returns path of the loaded plugin + fn path(&self) -> &str; + /// Returns the plugin's state (Declared, Loaded, Started) + fn state(&self) -> PluginState; + /// Returns the plugin's current report: a list of messages and the severity level + /// When status is changed, report is cleared + fn report(&self) -> PluginReport; + /// Returns all the information about the plugin in signed structure + fn status(&self) -> PluginStatus { + PluginStatus { + name: Cow::Borrowed(self.name()), + version: self.version().map(Cow::Borrowed), + path: Cow::Borrowed(self.path()), + state: self.state(), + report: self.report(), + } + } } pub trait PluginControl { diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 5fe15be8d3..40c39535bf 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -667,13 +667,7 @@ fn plugins_data(context: &AdminContext, query: Query) { log::debug!("plugin {} status: {:?}", name, status); let key = root_key.join(&name).unwrap(); let status = serde_json::to_value(status).unwrap(); - if let Err(e) = query - .reply(Ok(Sample::new( - key, - Value::from(status) - ))) - .res() - { + if let Err(e) = query.reply(Ok(Sample::new(key, Value::from(status)))).res() { log::error!("Error sending AdminSpace reply: {:?}", e); } } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 1f1e8ac69b..534acb9956 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -19,12 +19,12 @@ pub use crate::runtime::Runtime; pub use crate::Result as ZResult; use zenoh_core::zconfigurable; -use zenoh_plugin_trait::PluginReport; -use zenoh_plugin_trait::PluginStatus; -use zenoh_plugin_trait::PluginStructVersion; use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginInstance; +use zenoh_plugin_trait::PluginReport; +use zenoh_plugin_trait::PluginStatus; +use zenoh_plugin_trait::PluginStructVersion; use zenoh_protocol::core::key_expr::keyexpr; zconfigurable! { From d1e4b29ffcc37c87ae0faee4ce648a1e47b6e2f6 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 19 Nov 2023 14:43:08 +0100 Subject: [PATCH 055/106] status method removed from trait --- plugins/zenoh-backend-traits/src/lib.rs | 4 +-- .../zenoh-plugin-storage-manager/src/lib.rs | 4 +-- plugins/zenoh-plugin-trait/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/src/manager.rs | 24 ++++++++------ .../src/manager/dynamic_plugin.rs | 11 ++++++- .../src/manager/static_plugin.rs | 12 +++++-- plugins/zenoh-plugin-trait/src/plugin.rs | 33 ++++++++++--------- zenoh/src/plugins/sealed.rs | 4 +-- 8 files changed, 58 insertions(+), 36 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 5d4e100a66..0e1e9ecf74 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -140,7 +140,7 @@ use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; use zenoh_plugin_trait::{ - concat_enabled_features, PluginControl, PluginInstance, PluginStatus, PluginStructVersion, + concat_enabled_features, PluginControl, PluginInstance, PluginStatusRec, PluginStructVersion, }; pub mod config; @@ -235,7 +235,7 @@ impl PluginStructVersion for VolumePlugin { } impl PluginControl for VolumePlugin { - fn plugins_status(&self, _names: &zenoh::prelude::keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, _names: &zenoh::prelude::keyexpr) -> Vec<(String, PluginStatusRec)> { Vec::new() } } diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 46be81a4be..997b48971a 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -40,7 +40,7 @@ use zenoh_core::zlock; use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginReport; -use zenoh_plugin_trait::PluginStatus; +use zenoh_plugin_trait::PluginStatusRec; use zenoh_result::ZResult; use zenoh_util::LibLoader; @@ -247,7 +247,7 @@ impl PluginControl for StorageRuntime { fn report(&self) -> PluginReport { PluginReport::default() } - fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatusRec)> { let guard = self.0.lock().unwrap(); guard .plugins_manager diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 856689df9b..98bb8fa3f8 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -26,7 +26,7 @@ mod vtable; pub use manager::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; pub use plugin::{ Plugin, PluginConditionSetter, PluginControl, PluginInstance, PluginReport, PluginStartArgs, - PluginState, PluginStatus, PluginStatusGetter, PluginStructVersion, + PluginState, PluginStatus, PluginStatusRec, PluginStructVersion, }; pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index ae7daad689..cf5b12d644 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -23,18 +23,21 @@ use self::{ static_plugin::StaticPlugin, }; -pub trait DeclaredPlugin: PluginStatusGetter { +pub trait DeclaredPlugin: PluginStatus { + fn as_status(&self) -> &dyn PluginStatus; fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin>; fn loaded(&self) -> Option<&dyn LoadedPlugin>; fn loaded_mut(&mut self) -> Option<&mut dyn LoadedPlugin>; } -pub trait LoadedPlugin: PluginStatusGetter { +pub trait LoadedPlugin: PluginStatus { + fn as_status(&self) -> &dyn PluginStatus; fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin>; fn started(&self) -> Option<&dyn StartedPlugin>; fn started_mut(&mut self) -> Option<&mut dyn StartedPlugin>; } -pub trait StartedPlugin: PluginStatusGetter { +pub trait StartedPlugin: PluginStatus { + fn as_status(&self) -> &dyn PluginStatus; fn stop(&mut self); fn instance(&self) -> &Instance; fn instance_mut(&mut self) -> &mut Instance; @@ -50,7 +53,7 @@ impl PluginRecord PluginStatusGetter +impl PluginStatus for PluginRecord { fn name(&self) -> &str { @@ -68,14 +71,14 @@ impl PluginStatusGetter fn report(&self) -> PluginReport { self.0.report() } - fn status(&self) -> PluginStatus { - self.0.status() - } } impl DeclaredPlugin for PluginRecord { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { self.0.load() } @@ -260,17 +263,18 @@ impl impl PluginControl for PluginsManager { - fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatusRec)> { log::debug!( "Plugin manager with prefix `{}` : requested plugins_status {:?}", self.default_lib_prefix, names ); - let mut plugins: Vec<(String, PluginStatus)> = Vec::new(); + let mut plugins: Vec<(String, PluginStatusRec)> = Vec::new(); for plugin in self.declared_plugins() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; if names.includes(name) { - plugins.push((plugin.name().to_string(), plugin.status())); + let status = PluginStatusRec::new(plugin.as_status()); + plugins.push((plugin.name().to_string(), status)); } // for running plugins append their subplugins prepended with the running plugin name if let Some(plugin) = plugin.loaded() { diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index d4842e1e0d..e4df9ab7ab 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -121,7 +121,7 @@ impl DynamicPlugin { } } -impl PluginStatusGetter +impl PluginStatus for DynamicPlugin { fn name(&self) -> &str { @@ -161,6 +161,9 @@ impl PluginStatusGetter impl DeclaredPlugin for DynamicPlugin { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { if self.starter.is_none() { let (lib, path) = self.source.load().add_error(&mut self.report)?; @@ -191,6 +194,9 @@ impl DeclaredPlugin LoadedPlugin for DynamicPlugin { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { let starter = self .starter @@ -228,6 +234,9 @@ impl LoadedPlugin StartedPlugin for DynamicPlugin { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn stop(&mut self) { log::debug!("Plugin `{}` stopped", self.name); self.report.clear(); diff --git a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs index 1eb440bac8..46566c1545 100644 --- a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs @@ -35,8 +35,7 @@ where } } -impl PluginStatusGetter - for StaticPlugin +impl PluginStatus for StaticPlugin where P: Plugin, { @@ -68,6 +67,9 @@ impl DeclaredPlugin where P: Plugin, { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn load(&mut self) -> ZResult<&mut dyn LoadedPlugin> { Ok(self) } @@ -84,6 +86,9 @@ impl LoadedPlugin where P: Plugin, { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn start(&mut self, args: &StartArgs) -> ZResult<&mut dyn StartedPlugin> { if self.instance.is_none() { log::debug!("Plugin `{}` started", self.name()); @@ -114,6 +119,9 @@ impl StartedPlugin where P: Plugin, { + fn as_status(&self) -> &dyn PluginStatus { + self + } fn stop(&mut self) { log::debug!("Plugin `{}` stopped", self.name()); self.instance = None; diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 69c25f9b10..9a78434f31 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -59,7 +59,7 @@ pub struct PluginReport { /// The status of a plugin contains all information about the plugin in single cloneable structure #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct PluginStatus<'a> { +pub struct PluginStatusRec<'a> { pub name: Cow<'a, str>, #[serde(skip_serializing_if = "Option::is_none")] pub version: Option>, @@ -68,9 +68,20 @@ pub struct PluginStatus<'a> { pub report: PluginReport, } -impl PluginStatus<'_> { - pub fn into_owned(self) -> PluginStatus<'static> { - PluginStatus { +impl<'a> PluginStatusRec<'a> { + /// Construst status fructure from the getter interface + pub fn new(plugin: &'a T) -> Self { + Self { + name: Cow::Borrowed(plugin.name()), + version: plugin.version().map(Cow::Borrowed), + path: Cow::Borrowed(plugin.path()), + state: plugin.state(), + report: plugin.report(), + } + } + /// Convert status structure to owned version + pub fn into_owned(self) -> PluginStatusRec<'static> { + PluginStatusRec { name: Cow::Owned(self.name.into_owned()), version: self.version.map(|v| Cow::Owned(v.into_owned())), path: Cow::Owned(self.path.into_owned()), @@ -80,7 +91,7 @@ impl PluginStatus<'_> { } } -pub trait PluginStatusGetter { +pub trait PluginStatus { /// Returns name of the plugin fn name(&self) -> &str; /// Returns version of the loaded plugin (usually the version of the plugin's crate) @@ -92,16 +103,6 @@ pub trait PluginStatusGetter { /// Returns the plugin's current report: a list of messages and the severity level /// When status is changed, report is cleared fn report(&self) -> PluginReport; - /// Returns all the information about the plugin in signed structure - fn status(&self) -> PluginStatus { - PluginStatus { - name: Cow::Borrowed(self.name()), - version: self.version().map(Cow::Borrowed), - path: Cow::Borrowed(self.path()), - state: self.state(), - report: self.report(), - } - } } pub trait PluginControl { @@ -109,7 +110,7 @@ pub trait PluginControl { PluginReport::default() } /// Collect information of sub-plugins matching `_names` keyexpr - fn plugins_status(&self, _names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, _names: &keyexpr) -> Vec<(String, PluginStatusRec)> { Vec::new() } } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 534acb9956..3a4df52b83 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -23,7 +23,7 @@ use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginInstance; use zenoh_plugin_trait::PluginReport; -use zenoh_plugin_trait::PluginStatus; +use zenoh_plugin_trait::PluginStatusRec; use zenoh_plugin_trait::PluginStructVersion; use zenoh_protocol::core::key_expr::keyexpr; @@ -53,7 +53,7 @@ impl PluginControl for RunningPlugin { self.as_ref().report() } - fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatus)> { + fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatusRec)> { self.as_ref().plugins_status(names) } } From ce3f585e09ff7bd6c9ece1927b8150c2bca2aa3e Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 19 Nov 2023 15:01:46 +0100 Subject: [PATCH 056/106] removed tuple --- plugins/zenoh-backend-traits/src/lib.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 4 +- plugins/zenoh-plugin-trait/src/manager.rs | 10 ++-- plugins/zenoh-plugin-trait/src/plugin.rs | 57 +++++++++++++------ zenoh/src/net/runtime/adminspace.rs | 8 +-- zenoh/src/plugins/sealed.rs | 2 +- 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 0e1e9ecf74..090a377e9f 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -235,7 +235,7 @@ impl PluginStructVersion for VolumePlugin { } impl PluginControl for VolumePlugin { - fn plugins_status(&self, _names: &zenoh::prelude::keyexpr) -> Vec<(String, PluginStatusRec)> { + fn plugins_status(&self, _names: &zenoh::prelude::keyexpr) -> Vec { Vec::new() } } diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 997b48971a..1767201300 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -247,13 +247,13 @@ impl PluginControl for StorageRuntime { fn report(&self) -> PluginReport { PluginReport::default() } - fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatusRec)> { + fn plugins_status(&self, names: &keyexpr) -> Vec { let guard = self.0.lock().unwrap(); guard .plugins_manager .plugins_status(names) .into_iter() - .map(|(k, v)| (k, v.into_owned())) + .map(PluginStatusRec::into_owned) .collect() } } diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index cf5b12d644..ea6b88f671 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -263,18 +263,18 @@ impl impl PluginControl for PluginsManager { - fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatusRec)> { + fn plugins_status(&self, names: &keyexpr) -> Vec { log::debug!( "Plugin manager with prefix `{}` : requested plugins_status {:?}", self.default_lib_prefix, names ); - let mut plugins: Vec<(String, PluginStatusRec)> = Vec::new(); + let mut plugins = Vec::new(); for plugin in self.declared_plugins() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; if names.includes(name) { let status = PluginStatusRec::new(plugin.as_status()); - plugins.push((plugin.name().to_string(), status)); + plugins.push(status); } // for running plugins append their subplugins prepended with the running plugin name if let Some(plugin) = plugin.loaded() { @@ -284,8 +284,8 @@ impl P &mut plugin .instance() .plugins_status(names) - .iter() - .map(|(n, s)| (format!("{}/{}", name, n), s.clone())) + .into_iter() + .map(|s| s.prepend_name(name)) .collect(), ); } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 9a78434f31..21a978a26c 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -57,7 +57,22 @@ pub struct PluginReport { messages: Vec>, } -/// The status of a plugin contains all information about the plugin in single cloneable structure +/// Trait allowing to get all information about the plugin +pub trait PluginStatus { + /// Returns name of the plugin + fn name(&self) -> &str; + /// Returns version of the loaded plugin (usually the version of the plugin's crate) + fn version(&self) -> Option<&str>; + /// Returns path of the loaded plugin + fn path(&self) -> &str; + /// Returns the plugin's state (Declared, Loaded, Started) + fn state(&self) -> PluginState; + /// Returns the plugin's current report: a list of messages and the severity level + /// When status is changed, report is cleared + fn report(&self) -> PluginReport; +} + +/// The structure which contains all information about the plugin status in single cloneable structure #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PluginStatusRec<'a> { pub name: Cow<'a, str>, @@ -68,6 +83,24 @@ pub struct PluginStatusRec<'a> { pub report: PluginReport, } +impl PluginStatus for PluginStatusRec<'_> { + fn name(&self) -> &str { + &self.name + } + fn version(&self) -> Option<&str> { + self.version.as_deref() + } + fn path(&self) -> &str { + &self.path + } + fn state(&self) -> PluginState { + self.state + } + fn report(&self) -> PluginReport { + self.report.clone() + } +} + impl<'a> PluginStatusRec<'a> { /// Construst status fructure from the getter interface pub fn new(plugin: &'a T) -> Self { @@ -89,20 +122,12 @@ impl<'a> PluginStatusRec<'a> { report: self.report, } } -} - -pub trait PluginStatus { - /// Returns name of the plugin - fn name(&self) -> &str; - /// Returns version of the loaded plugin (usually the version of the plugin's crate) - fn version(&self) -> Option<&str>; - /// Returns path of the loaded plugin - fn path(&self) -> &str; - /// Returns the plugin's state (Declared, Loaded, Started) - fn state(&self) -> PluginState; - /// Returns the plugin's current report: a list of messages and the severity level - /// When status is changed, report is cleared - fn report(&self) -> PluginReport; + pub(crate) fn prepend_name(self, prefix: &str) -> Self { + Self { + name: Cow::Owned(format!("{}/{}", prefix, self.name)), + ..self + } + } } pub trait PluginControl { @@ -110,7 +135,7 @@ pub trait PluginControl { PluginReport::default() } /// Collect information of sub-plugins matching `_names` keyexpr - fn plugins_status(&self, _names: &keyexpr) -> Vec<(String, PluginStatusRec)> { + fn plugins_status(&self, _names: &keyexpr) -> Vec { Vec::new() } } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 40c39535bf..637ec01809 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -28,7 +28,7 @@ use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::SplitBuffer; use zenoh_config::{ConfigValidator, ValidatedMap}; -use zenoh_plugin_trait::PluginControl; +use zenoh_plugin_trait::{PluginControl, PluginStatus}; use zenoh_protocol::core::key_expr::keyexpr; use zenoh_protocol::{ core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, @@ -663,9 +663,9 @@ fn plugins_data(context: &AdminContext, query: Query) { log::debug!("requested plugins status {:?}", query.key_expr()); if let [names, ..] = query.key_expr().strip_prefix(root_key)[..] { let statuses = guard.plugins_status(names); - for (name, status) in statuses { - log::debug!("plugin {} status: {:?}", name, status); - let key = root_key.join(&name).unwrap(); + for status in statuses { + log::debug!("plugin status: {:?}", status); + let key = root_key.join(status.name()).unwrap(); let status = serde_json::to_value(status).unwrap(); if let Err(e) = query.reply(Ok(Sample::new(key, Value::from(status)))).res() { log::error!("Error sending AdminSpace reply: {:?}", e); diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 3a4df52b83..f3c31be2ea 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -53,7 +53,7 @@ impl PluginControl for RunningPlugin { self.as_ref().report() } - fn plugins_status(&self, names: &keyexpr) -> Vec<(String, PluginStatusRec)> { + fn plugins_status(&self, names: &keyexpr) -> Vec { self.as_ref().plugins_status(names) } } From 0d403ab9df09c0bbeb012b125ff432a647e80aa3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 20 Nov 2023 10:34:58 +0100 Subject: [PATCH 057/106] format fix --- plugins/zenoh-backend-traits/src/config.rs | 2 +- zenoh/src/net/runtime/mod.rs | 2 +- zenohd/src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index fe089a23e5..e3ccd2f524 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -18,7 +18,7 @@ use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; -use zenoh_plugin_trait::{PluginStructVersion, PluginStartArgs}; +use zenoh_plugin_trait::{PluginStartArgs, PluginStructVersion}; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 912b2a298f..42c317d571 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -37,7 +37,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::{PluginStructVersion, PluginStartArgs}; +use zenoh_plugin_trait::{PluginStartArgs, PluginStructVersion}; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 087e4be87f..0e59364c24 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -15,12 +15,12 @@ use async_std::task; use clap::{ArgMatches, Command}; use futures::future; use git_version::git_version; -use zenoh::Result; use std::collections::HashSet; use zenoh::config::{Config, ModeDependentValue, PermissionsConf, PluginLoad, ValidatedMap}; use zenoh::plugins::PluginsManager; use zenoh::prelude::{EndPoint, WhatAmI}; use zenoh::runtime::{AdminSpace, Runtime}; +use zenoh::Result; const GIT_VERSION: &str = git_version!(prefix = "v", cargo_prefix = "v"); From 2e5b259a156c728994d2adfa4aa40e430edf31ae Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 20 Nov 2023 21:20:33 +0100 Subject: [PATCH 058/106] commented out plugins section in config sample --- DEFAULT_CONFIG.json5 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index a98434f78c..b06ef4c4eb 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -393,18 +393,18 @@ // }, // }, - /// Plugin configuration example using `__config__` property - plugins: { - rest: { - __config__: "./plugins/zenoh-plugin-rest/config.json5", - }, - storage_manager: { - __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - }, - not_found: { - }, - example: { - }, - }, + ///// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // }, + // not_found: { + // }, + // example: { + // }, + //}, } From c7e51bf05c2727c50a432ccebd8294addabffb15 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 20 Nov 2023 22:18:25 +0100 Subject: [PATCH 059/106] doc test fixed --- plugins/zenoh-backend-traits/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 090a377e9f..9ec26cf1a5 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -62,7 +62,7 @@ //! } //! } //! -//! async fn create_storage(&mut self, properties: StorageConfig) -> ZResult> { +//! async fn create_storage(&self, properties: StorageConfig) -> ZResult> { //! // The properties are the ones passed via a PUT in the admin space for Storage creation. //! Ok(Box::new(MyStorage::new(properties).await?)) //! } From 785a76f6dff1ba8913bb41c4a4df0d098a849cdd Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 23 Nov 2023 09:29:19 +0100 Subject: [PATCH 060/106] no-mangled feature added to test --- plugins/zenoh-plugin-trait/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 98bb8fa3f8..6a2a689dd9 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -42,5 +42,7 @@ macro_rules! concat_enabled_features { }; } -pub const FEATURES: &str = - concat_enabled_features!(prefix = "zenoh-plugin-trait", features = ["default"]); +pub const FEATURES: &str = concat_enabled_features!( + prefix = "zenoh-plugin-trait", + features = ["default", "no_mangle"] +); From d5c95f94412e26b7e4b84a4af65cfd48a50cc269 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 27 Nov 2023 14:20:37 +0000 Subject: [PATCH 061/106] test for default zenohd features --- Cargo.lock | 2 ++ commons/zenoh-util/Cargo.toml | 1 + commons/zenoh-util/src/lib.rs | 13 +++++++++++++ zenoh/Cargo.toml | 1 + zenoh/src/lib.rs | 23 +++++++++++++++++++++++ zenohd/src/main.rs | 22 ++++++++++++++++++++++ 6 files changed, 62 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b01f2d25e9..1cc18137ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4483,6 +4483,7 @@ dependencies = [ "async-std", "async-trait", "base64 0.21.4", + "const_format", "env_logger", "event-listener", "flume", @@ -5028,6 +5029,7 @@ dependencies = [ "async-std", "async-trait", "clap 3.2.25", + "const_format", "flume", "futures", "hex", diff --git a/commons/zenoh-util/Cargo.toml b/commons/zenoh-util/Cargo.toml index 8225ab534e..803645fb8a 100644 --- a/commons/zenoh-util/Cargo.toml +++ b/commons/zenoh-util/Cargo.toml @@ -39,6 +39,7 @@ default = ["std"] async-std = { workspace = true, features = ["default", "unstable"] } async-trait = { workspace = true } clap = { workspace = true } +const_format = { workspace = true } flume = { workspace = true } futures = { workspace = true } hex = { workspace = true, features = ["default"] } diff --git a/commons/zenoh-util/src/lib.rs b/commons/zenoh-util/src/lib.rs index 9739074bb3..9e84c5cae2 100644 --- a/commons/zenoh-util/src/lib.rs +++ b/commons/zenoh-util/src/lib.rs @@ -22,6 +22,18 @@ extern crate alloc; #[cfg_attr(feature = "std", macro_use)] extern crate lazy_static; +#[macro_export] +macro_rules! concat_enabled_features { + (prefix = $prefix:literal, features = [$($feature:literal),*]) => { + { + use const_format::concatcp; + concatcp!("" $(, + if cfg!(feature = $feature) { concatcp!(" ", concatcp!($prefix, "/", $feature)) } else { "" } + )*) + } + }; +} + #[deprecated = "This module is now a separate crate. Use the `zenoh_core` crate directly for shorter compile-times. You may disable this re-export by disabling `zenoh-util`'s default features."] pub use zenoh_core as core; @@ -30,3 +42,4 @@ mod std_only; #[cfg(feature = "std")] pub use std_only::*; + diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 1fa34eab32..053bb7e285 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -65,6 +65,7 @@ async-global-executor = { workspace = true } async-std = { workspace = true, features = ["attributes"] } async-trait = { workspace = true } base64 = { workspace = true } +const_format = { workspace = true } env_logger = { workspace = true } event-listener = { workspace = true } flume = { workspace = true } diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index d77a205d50..59f9d6ced3 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -85,6 +85,7 @@ use handlers::DefaultHandler; use net::runtime::Runtime; use prelude::*; use scouting::ScoutBuilder; +use zenoh_util::concat_enabled_features; use std::future::Ready; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_macros::{kedefine, keformat, kewrite}; @@ -98,6 +99,28 @@ pub use zenoh_result::ZResult as Result; const GIT_VERSION: &str = git_version!(prefix = "v", cargo_prefix = "v"); +pub const FEATURES: &str = concat_enabled_features!( + prefix = "zenoh", + features = [ + "auth_pubkey", + "auth_usrpwd", + "complete_n", + "shared-memory", + "stats", + "transport_multilink", + "transport_quic", + "transport_serial", + "transport_unixpipe", + "transport_tcp", + "transport_tls", + "transport_udp", + "transport_unixsock-stream", + "transport_ws", + "unstable", + "default" + ] +); + mod admin; #[macro_use] mod session; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index 2b23604c83..eef8432775 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -307,3 +307,25 @@ fn config_from_args(args: &ArgMatches) -> Config { log::debug!("Config: {:?}", &config); config } + +#[test] +fn test_default_features() { + assert_eq!(zenoh::FEATURES, concat!( + " zenoh/auth_pubkey", + " zenoh/auth_usrpwd", + // " zenoh/complete_n", + // " zenoh/shared-memory", + // " zenoh/stats", + " zenoh/transport_multilink", + " zenoh/transport_quic", + // " zenoh/transport_serial", + // " zenoh/transport_unixpipe", + " zenoh/transport_tcp", + " zenoh/transport_tls", + " zenoh/transport_udp", + " zenoh/transport_unixsock-stream", + " zenoh/transport_ws", + " zenoh/unstable", + " zenoh/default", + )); +} \ No newline at end of file From e77acb8ad90c9671149cd87390e1613e513c0d7a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 27 Nov 2023 15:01:49 +0000 Subject: [PATCH 062/106] tests added, leaking through zenoh-ext fixed --- Cargo.toml | 2 +- zenoh-ext/Cargo.toml | 2 +- zenoh-ext/src/lib.rs | 8 ++++++++ zenohd/Cargo.toml | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a707ab390c..55797ab0d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -185,7 +185,7 @@ zenoh-link-unixpipe = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-lin zenoh-link-serial = { version = "0.11.0-dev", path = "io/zenoh-links/zenoh-link-serial" } zenoh-link = { version = "0.11.0-dev", path = "io/zenoh-link" } zenoh-link-commons = { version = "0.11.0-dev", path = "io/zenoh-link-commons" } -zenoh = { version = "0.11.0-dev", path = "zenoh" } +zenoh = { version = "0.11.0-dev", path = "zenoh", default-features = false } [profile.dev] debug = true diff --git a/zenoh-ext/Cargo.toml b/zenoh-ext/Cargo.toml index 26164040db..84c6baf83c 100644 --- a/zenoh-ext/Cargo.toml +++ b/zenoh-ext/Cargo.toml @@ -38,7 +38,7 @@ flume = { workspace = true } futures = { workspace = true } log = { workspace = true } serde = { workspace = true, features = ["default"] } -zenoh = { workspace = true, features = ["unstable"] } +zenoh = { workspace = true, features = ["unstable"], default-features = false } zenoh-core = { workspace = true } zenoh-macros = { workspace = true } zenoh-result = { workspace = true } diff --git a/zenoh-ext/src/lib.rs b/zenoh-ext/src/lib.rs index dca488ba80..395ffac092 100644 --- a/zenoh-ext/src/lib.rs +++ b/zenoh-ext/src/lib.rs @@ -51,3 +51,11 @@ impl From for KeySpace { KeySpace::Liveliness } } + +#[test] +fn test_default_features() { + // make sure that when inporting zenoh-ext with default features, no unwanted features are pulled from zenoh-core + assert_eq!(zenoh::FEATURES, concat!( + " zenoh/unstable", + )); +} \ No newline at end of file diff --git a/zenohd/Cargo.toml b/zenohd/Cargo.toml index e589d1a888..b28a28331b 100644 --- a/zenohd/Cargo.toml +++ b/zenohd/Cargo.toml @@ -37,7 +37,7 @@ git-version = { workspace = true } json5 = { workspace = true } lazy_static = { workspace = true } log = { workspace = true } -zenoh = { workspace = true, features = ["unstable"] } +zenoh = { workspace = true, default-features = true, features = ["unstable"] } [dev-dependencies] rand = { workspace = true, features = ["default"] } From d7b0ea8816a460e1d44c3605ea2d67f9221a99e8 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 28 Nov 2023 14:02:04 +0000 Subject: [PATCH 063/106] no feature test added --- .github/workflows/ci.yml | 7 +++++++ zenohd/Cargo.toml | 3 ++- zenohd/src/main.rs | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e24616f6e..60fb69a576 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,6 +112,13 @@ jobs: CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse ASYNC_STD_THREAD_COUNT: 4 + - name: Check for feature leaks + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions-rs/cargo@v1 + with: + command: nextest + args: run -p zenohd --no-default-features + - name: Run doctests uses: actions-rs/cargo@v1 with: diff --git a/zenohd/Cargo.toml b/zenohd/Cargo.toml index b28a28331b..754198dc73 100644 --- a/zenohd/Cargo.toml +++ b/zenohd/Cargo.toml @@ -26,6 +26,7 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +default = ["zenoh/default"] shared-memory = ["zenoh/shared-memory"] [dependencies] @@ -37,7 +38,7 @@ git-version = { workspace = true } json5 = { workspace = true } lazy_static = { workspace = true } log = { workspace = true } -zenoh = { workspace = true, default-features = true, features = ["unstable"] } +zenoh = { workspace = true, features = ["unstable"] } [dev-dependencies] rand = { workspace = true, features = ["default"] } diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index eef8432775..cc28234e74 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -309,6 +309,7 @@ fn config_from_args(args: &ArgMatches) -> Config { } #[test] +#[cfg(feature = "default")] fn test_default_features() { assert_eq!(zenoh::FEATURES, concat!( " zenoh/auth_pubkey", @@ -328,4 +329,27 @@ fn test_default_features() { " zenoh/unstable", " zenoh/default", )); +} + +#[test] +#[cfg(not(feature = "default"))] +fn test_no_default_features() { + assert_eq!(zenoh::FEATURES, concat!( + // " zenoh/auth_pubkey", + // " zenoh/auth_usrpwd", + // " zenoh/complete_n", + // " zenoh/shared-memory", + // " zenoh/stats", + // " zenoh/transport_multilink", + // " zenoh/transport_quic", + // " zenoh/transport_serial", + // " zenoh/transport_unixpipe", + // " zenoh/transport_tcp", + // " zenoh/transport_tls", + // " zenoh/transport_udp", + // " zenoh/transport_unixsock-stream", + // " zenoh/transport_ws", + " zenoh/unstable", + // " zenoh/default", + )); } \ No newline at end of file From 6a4b3667e37e91b9ca593047ee3547c5bffb3966 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 28 Nov 2023 14:22:27 +0000 Subject: [PATCH 064/106] cargo fmt --- commons/zenoh-util/src/lib.rs | 1 - zenoh-ext/src/lib.rs | 6 +-- zenoh/src/lib.rs | 2 +- zenohd/src/main.rs | 80 +++++++++++++++++++---------------- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/commons/zenoh-util/src/lib.rs b/commons/zenoh-util/src/lib.rs index 9e84c5cae2..7e02096ebb 100644 --- a/commons/zenoh-util/src/lib.rs +++ b/commons/zenoh-util/src/lib.rs @@ -42,4 +42,3 @@ mod std_only; #[cfg(feature = "std")] pub use std_only::*; - diff --git a/zenoh-ext/src/lib.rs b/zenoh-ext/src/lib.rs index 395ffac092..b805ca18b7 100644 --- a/zenoh-ext/src/lib.rs +++ b/zenoh-ext/src/lib.rs @@ -55,7 +55,5 @@ impl From for KeySpace { #[test] fn test_default_features() { // make sure that when inporting zenoh-ext with default features, no unwanted features are pulled from zenoh-core - assert_eq!(zenoh::FEATURES, concat!( - " zenoh/unstable", - )); -} \ No newline at end of file + assert_eq!(zenoh::FEATURES, concat!(" zenoh/unstable",)); +} diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index 59f9d6ced3..5c3b938e5b 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -85,12 +85,12 @@ use handlers::DefaultHandler; use net::runtime::Runtime; use prelude::*; use scouting::ScoutBuilder; -use zenoh_util::concat_enabled_features; use std::future::Ready; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_macros::{kedefine, keformat, kewrite}; use zenoh_protocol::core::WhatAmIMatcher; use zenoh_result::{zerror, ZResult}; +use zenoh_util::concat_enabled_features; /// A zenoh error. pub use zenoh_result::Error; diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index cc28234e74..56c56bc538 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -311,45 +311,51 @@ fn config_from_args(args: &ArgMatches) -> Config { #[test] #[cfg(feature = "default")] fn test_default_features() { - assert_eq!(zenoh::FEATURES, concat!( - " zenoh/auth_pubkey", - " zenoh/auth_usrpwd", - // " zenoh/complete_n", - // " zenoh/shared-memory", - // " zenoh/stats", - " zenoh/transport_multilink", - " zenoh/transport_quic", - // " zenoh/transport_serial", - // " zenoh/transport_unixpipe", - " zenoh/transport_tcp", - " zenoh/transport_tls", - " zenoh/transport_udp", - " zenoh/transport_unixsock-stream", - " zenoh/transport_ws", - " zenoh/unstable", - " zenoh/default", - )); + assert_eq!( + zenoh::FEATURES, + concat!( + " zenoh/auth_pubkey", + " zenoh/auth_usrpwd", + // " zenoh/complete_n", + // " zenoh/shared-memory", + // " zenoh/stats", + " zenoh/transport_multilink", + " zenoh/transport_quic", + // " zenoh/transport_serial", + // " zenoh/transport_unixpipe", + " zenoh/transport_tcp", + " zenoh/transport_tls", + " zenoh/transport_udp", + " zenoh/transport_unixsock-stream", + " zenoh/transport_ws", + " zenoh/unstable", + " zenoh/default", + ) + ); } #[test] #[cfg(not(feature = "default"))] fn test_no_default_features() { - assert_eq!(zenoh::FEATURES, concat!( - // " zenoh/auth_pubkey", - // " zenoh/auth_usrpwd", - // " zenoh/complete_n", - // " zenoh/shared-memory", - // " zenoh/stats", - // " zenoh/transport_multilink", - // " zenoh/transport_quic", - // " zenoh/transport_serial", - // " zenoh/transport_unixpipe", - // " zenoh/transport_tcp", - // " zenoh/transport_tls", - // " zenoh/transport_udp", - // " zenoh/transport_unixsock-stream", - // " zenoh/transport_ws", - " zenoh/unstable", - // " zenoh/default", - )); -} \ No newline at end of file + assert_eq!( + zenoh::FEATURES, + concat!( + // " zenoh/auth_pubkey", + // " zenoh/auth_usrpwd", + // " zenoh/complete_n", + // " zenoh/shared-memory", + // " zenoh/stats", + // " zenoh/transport_multilink", + // " zenoh/transport_quic", + // " zenoh/transport_serial", + // " zenoh/transport_unixpipe", + // " zenoh/transport_tcp", + // " zenoh/transport_tls", + // " zenoh/transport_udp", + // " zenoh/transport_unixsock-stream", + // " zenoh/transport_ws", + " zenoh/unstable", + // " zenoh/default", + ) + ); +} From a0fd9312e3bb2b6189fce329bd94ade2d7d7097c Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 28 Nov 2023 14:30:57 +0000 Subject: [PATCH 065/106] removed global Arc import as it's under features --- io/zenoh-link/src/lib.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/io/zenoh-link/src/lib.rs b/io/zenoh-link/src/lib.rs index 9d49853501..b298b9caf9 100644 --- a/io/zenoh-link/src/lib.rs +++ b/io/zenoh-link/src/lib.rs @@ -18,7 +18,6 @@ //! //! [Click here for Zenoh's documentation](../zenoh/index.html) use std::collections::HashMap; -use std::sync::Arc; use zenoh_config::Config; use zenoh_result::{bail, ZResult}; @@ -206,23 +205,23 @@ impl LinkManagerBuilderUnicast { pub fn make(_manager: NewLinkChannelSender, protocol: &str) -> ZResult { match protocol { #[cfg(feature = "transport_tcp")] - TCP_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastTcp::new(_manager))), + TCP_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastTcp::new(_manager))), #[cfg(feature = "transport_udp")] - UDP_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastUdp::new(_manager))), + UDP_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastUdp::new(_manager))), #[cfg(feature = "transport_tls")] - TLS_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastTls::new(_manager))), + TLS_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastTls::new(_manager))), #[cfg(feature = "transport_quic")] - QUIC_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastQuic::new(_manager))), + QUIC_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastQuic::new(_manager))), #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] UNIXSOCKSTREAM_LOCATOR_PREFIX => { - Ok(Arc::new(LinkManagerUnicastUnixSocketStream::new(_manager))) + Ok(std::sync::Arc::new(LinkManagerUnicastUnixSocketStream::new(_manager))) } #[cfg(feature = "transport_ws")] - WS_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastWs::new(_manager))), + WS_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastWs::new(_manager))), #[cfg(feature = "transport_serial")] - SERIAL_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastSerial::new(_manager))), + SERIAL_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastSerial::new(_manager))), #[cfg(feature = "transport_unixpipe")] - UNIXPIPE_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerUnicastPipe::new(_manager))), + UNIXPIPE_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastPipe::new(_manager))), _ => bail!("Unicast not supported for {} protocol", protocol), } } @@ -238,7 +237,7 @@ impl LinkManagerBuilderMulticast { pub fn make(protocol: &str) -> ZResult { match protocol { #[cfg(feature = "transport_udp")] - UDP_LOCATOR_PREFIX => Ok(Arc::new(LinkManagerMulticastUdp)), + UDP_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerMulticastUdp)), _ => bail!("Multicast not supported for {} protocol", protocol), } } From bd051fad6e8214790981932cdba6fe2f319d0ddd Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 28 Nov 2023 14:33:10 +0000 Subject: [PATCH 066/106] cargo fmt --- io/zenoh-link/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/io/zenoh-link/src/lib.rs b/io/zenoh-link/src/lib.rs index b298b9caf9..18a464cb93 100644 --- a/io/zenoh-link/src/lib.rs +++ b/io/zenoh-link/src/lib.rs @@ -213,15 +213,19 @@ impl LinkManagerBuilderUnicast { #[cfg(feature = "transport_quic")] QUIC_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastQuic::new(_manager))), #[cfg(all(feature = "transport_unixsock-stream", target_family = "unix"))] - UNIXSOCKSTREAM_LOCATOR_PREFIX => { - Ok(std::sync::Arc::new(LinkManagerUnicastUnixSocketStream::new(_manager))) - } + UNIXSOCKSTREAM_LOCATOR_PREFIX => Ok(std::sync::Arc::new( + LinkManagerUnicastUnixSocketStream::new(_manager), + )), #[cfg(feature = "transport_ws")] WS_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastWs::new(_manager))), #[cfg(feature = "transport_serial")] - SERIAL_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastSerial::new(_manager))), + SERIAL_LOCATOR_PREFIX => { + Ok(std::sync::Arc::new(LinkManagerUnicastSerial::new(_manager))) + } #[cfg(feature = "transport_unixpipe")] - UNIXPIPE_LOCATOR_PREFIX => Ok(std::sync::Arc::new(LinkManagerUnicastPipe::new(_manager))), + UNIXPIPE_LOCATOR_PREFIX => { + Ok(std::sync::Arc::new(LinkManagerUnicastPipe::new(_manager))) + } _ => bail!("Unicast not supported for {} protocol", protocol), } } From b358102888e43ab6a1f6e411aee20156b9ffbf4f Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 28 Nov 2023 15:19:32 +0000 Subject: [PATCH 067/106] removed incorrect test, right one in zenohd --- zenoh-ext/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/zenoh-ext/src/lib.rs b/zenoh-ext/src/lib.rs index b805ca18b7..dca488ba80 100644 --- a/zenoh-ext/src/lib.rs +++ b/zenoh-ext/src/lib.rs @@ -51,9 +51,3 @@ impl From for KeySpace { KeySpace::Liveliness } } - -#[test] -fn test_default_features() { - // make sure that when inporting zenoh-ext with default features, no unwanted features are pulled from zenoh-core - assert_eq!(zenoh::FEATURES, concat!(" zenoh/unstable",)); -} From eaa7b9649d917d35d588a9ab2357cf959e2ebfb6 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 29 Nov 2023 09:07:31 +0100 Subject: [PATCH 068/106] duplicated import fix --- zenoh/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 22a5761239..0e372e9c84 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -66,7 +66,6 @@ async-std = { workspace = true, features = ["attributes"] } async-trait = { workspace = true } const_format = { workspace = true } base64 = { workspace = true } -const_format = { workspace = true } env_logger = { workspace = true } event-listener = { workspace = true } flume = { workspace = true } From 3b7a188627fe94f3dbb08a00d1437f0fa4e340ca Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 29 Nov 2023 09:27:46 +0100 Subject: [PATCH 069/106] compilation fix --- plugins/zenoh-plugin-trait/src/lib.rs | 13 +------------ zenoh/src/lib.rs | 1 - zenoh/src/session.rs | 3 ++- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 6a2a689dd9..d2f8a32819 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -29,18 +29,7 @@ pub use plugin::{ PluginState, PluginStatus, PluginStatusRec, PluginStructVersion, }; pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; - -#[macro_export] -macro_rules! concat_enabled_features { - (prefix = $prefix:literal, features = [$($feature:literal),*]) => { - { - use const_format::concatcp; - concatcp!("" $(, - if cfg!(feature = $feature) { concatcp!(" ", concatcp!($prefix, "/", $feature)) } else { "" } - )*) - } - }; -} +use zenoh_util::concat_enabled_features; pub const FEATURES: &str = concat_enabled_features!( prefix = "zenoh-plugin-trait", diff --git a/zenoh/src/lib.rs b/zenoh/src/lib.rs index 44a1b5c407..5c3b938e5b 100644 --- a/zenoh/src/lib.rs +++ b/zenoh/src/lib.rs @@ -88,7 +88,6 @@ use scouting::ScoutBuilder; use std::future::Ready; use zenoh_core::{AsyncResolve, Resolvable, SyncResolve}; pub use zenoh_macros::{kedefine, keformat, kewrite}; -use zenoh_plugin_trait::concat_enabled_features; use zenoh_protocol::core::WhatAmIMatcher; use zenoh_result::{zerror, ZResult}; use zenoh_util::concat_enabled_features; diff --git a/zenoh/src/session.rs b/zenoh/src/session.rs index f1e40d3360..64df927e11 100644 --- a/zenoh/src/session.rs +++ b/zenoh/src/session.rs @@ -1491,7 +1491,8 @@ impl Session { ) -> ZResult { use crate::net::routing::router::RoutingExpr; use zenoh_protocol::core::WhatAmI; - let tables = zread!(self.runtime.router.tables.tables); + let router = self.runtime.router(); + let tables = zread!(router.tables.tables); let res = crate::net::routing::resource::Resource::get_resource( &tables.root_res, key_expr.as_str(), From 8c8e5028a23ca405d5c1bbe896b628cd3bfc161f Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 29 Nov 2023 09:45:53 +0100 Subject: [PATCH 070/106] compilation fix --- plugins/zenoh-backend-traits/src/lib.rs | 5 ++--- zenoh/Cargo.toml | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 9ec26cf1a5..7654250660 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -139,9 +139,8 @@ use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; -use zenoh_plugin_trait::{ - concat_enabled_features, PluginControl, PluginInstance, PluginStatusRec, PluginStructVersion, -}; +use zenoh_plugin_trait::{PluginControl, PluginInstance, PluginStatusRec, PluginStructVersion}; +use zenoh_util::concat_enabled_features; pub mod config; use config::{StorageConfig, VolumeConfig}; diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 22a5761239..0e372e9c84 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -66,7 +66,6 @@ async-std = { workspace = true, features = ["attributes"] } async-trait = { workspace = true } const_format = { workspace = true } base64 = { workspace = true } -const_format = { workspace = true } env_logger = { workspace = true } event-listener = { workspace = true } flume = { workspace = true } From 297b202cd8e21b5f51562f0c21922f1fba346610 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 30 Nov 2023 14:46:01 +0000 Subject: [PATCH 071/106] compilation fix --- zenoh/src/net/runtime/adminspace.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 6983b1945b..73604e0e81 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -21,13 +21,15 @@ use crate::value::Value; use async_std::task; use log::{error, trace}; use serde_json::json; +use zenoh_plugin_trait::{PluginControl, PluginStatus}; +use zenoh_protocol::core::key_expr::keyexpr; use std::collections::HashMap; use std::convert::TryFrom; use std::convert::TryInto; use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::buffer::SplitBuffer; -use zenoh_config::ValidatedMap; +use zenoh_config::{ValidatedMap, ConfigValidator}; use zenoh_protocol::{ core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, network::{ From fc53c385c135e31b3a0017de91c267e500ed8c47 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 30 Nov 2023 17:03:19 +0000 Subject: [PATCH 072/106] compilation errors fixed --- plugins/example-plugin/Cargo.toml | 2 +- zenoh/Cargo.toml | 2 +- zenoh/build.rs | 1 - zenoh/src/net/routing/face.rs | 2 ++ zenoh/src/net/routing/resource.rs | 2 +- zenoh/src/net/routing/router.rs | 2 +- zenoh/src/plugins/sealed.rs | 7 +------ 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/plugins/example-plugin/Cargo.toml b/plugins/example-plugin/Cargo.toml index 40665afef4..a0b279d733 100644 --- a/plugins/example-plugin/Cargo.toml +++ b/plugins/example-plugin/Cargo.toml @@ -39,7 +39,7 @@ env_logger = { workspace = true } futures = { workspace = true } log = { workspace = true } serde_json = { workspace = true } -zenoh = { workspace = true, features = [ "unstable" ] } +zenoh = { workspace = true } zenoh-core = { workspace = true } zenoh-plugin-trait = { workspace = true } zenoh-result = { workspace = true } diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index dee651c527..0177c2d454 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -66,8 +66,8 @@ default = [ async-global-executor = { workspace = true } async-std = { workspace = true, features = ["attributes"] } async-trait = { workspace = true } -const_format = { workspace = true } base64 = { workspace = true } +const_format = { workspace = true } env_logger = { workspace = true } event-listener = { workspace = true } flume = { workspace = true } diff --git a/zenoh/build.rs b/zenoh/build.rs index 5be8828dfc..85d3c2d187 100644 --- a/zenoh/build.rs +++ b/zenoh/build.rs @@ -10,7 +10,6 @@ // Contributors: // ZettaScale Zenoh Team, // - fn main() { // Add rustc version to zenohd let version_meta = rustc_version::version_meta().unwrap(); diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 0d2ee926d1..7616420ec8 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -31,6 +31,7 @@ pub struct FaceState { pub(super) id: usize, pub(super) zid: ZenohId, pub(super) whatami: WhatAmI, + #[allow(dead_code)] pub(super) local: bool, #[cfg(feature = "stats")] pub(super) stats: Option>, @@ -80,6 +81,7 @@ impl FaceState { }) } + #[cfg(feature = "unstable")] #[inline] pub fn is_local(&self) -> bool { self.local diff --git a/zenoh/src/net/routing/resource.rs b/zenoh/src/net/routing/resource.rs index 2b60a301ea..00189b85c9 100644 --- a/zenoh/src/net/routing/resource.rs +++ b/zenoh/src/net/routing/resource.rs @@ -363,7 +363,7 @@ impl Resource { } } - #[allow(dead_code)] + #[cfg(test)] pub fn print_tree(from: &Arc) -> String { let mut result = from.expr(); result.push('\n'); diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index cc6b55d5b0..933bd7339c 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -142,7 +142,7 @@ impl Tables { &self.root_res } - #[allow(dead_code)] + #[cfg(test)] pub fn print(&self) -> String { Resource::print_tree(&self.root_res) } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index f3c31be2ea..573c18ab60 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -19,12 +19,7 @@ pub use crate::runtime::Runtime; pub use crate::Result as ZResult; use zenoh_core::zconfigurable; -use zenoh_plugin_trait::Plugin; -use zenoh_plugin_trait::PluginControl; -use zenoh_plugin_trait::PluginInstance; -use zenoh_plugin_trait::PluginReport; -use zenoh_plugin_trait::PluginStatusRec; -use zenoh_plugin_trait::PluginStructVersion; +use zenoh_plugin_trait::{Plugin, PluginControl, PluginInstance, PluginReport, PluginStatusRec, PluginStructVersion}; use zenoh_protocol::core::key_expr::keyexpr; zconfigurable! { From 4439ce3635b75a7a54b482cc961f9facf139ac86 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 4 Dec 2023 15:22:27 +0100 Subject: [PATCH 073/106] nom_mangle in lib removed --- DEFAULT_CONFIG.json5 | 26 ++++---- plugins/example-plugin/Cargo.toml | 2 +- plugins/zenoh-backend-traits/src/lib.rs | 2 + plugins/zenoh-plugin-rest/Cargo.toml | 2 +- .../zenoh-plugin-storage-manager/Cargo.toml | 2 +- plugins/zenoh-plugin-trait/Cargo.toml | 4 -- plugins/zenoh-plugin-trait/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/src/vtable.rs | 64 ++++++++----------- 8 files changed, 47 insertions(+), 57 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index d1bfe08408..fd3d08d942 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -406,18 +406,18 @@ // }, // }, - ///// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // }, - // not_found: { - // }, - // example: { - // }, - //}, + /// Plugin configuration example using `__config__` property + plugins: { + rest: { + __config__: "./plugins/zenoh-plugin-rest/config.json5", + }, + storage_manager: { + __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + }, + not_found: { + }, + example: { + }, + }, } diff --git a/plugins/example-plugin/Cargo.toml b/plugins/example-plugin/Cargo.toml index 324e676d0a..6091635191 100644 --- a/plugins/example-plugin/Cargo.toml +++ b/plugins/example-plugin/Cargo.toml @@ -21,7 +21,7 @@ publish = false [features] default = ["no_mangle"] -no_mangle = ["zenoh-plugin-trait/no_mangle"] +no_mangle = [] [lib] # When auto-detecting the "example" plugin, `zenohd` will look for a dynamic library named "zenoh_plugin_example" diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 7654250660..b7b7c9220a 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -14,6 +14,8 @@ //! ⚠️ WARNING ⚠️ //! +//! TODO: The example is outdated, rewrite it +//! //! This crate should be considered unstable, as in we might change the APIs anytime. //! //! This crate provides the traits to be implemented by a zenoh backend library: diff --git a/plugins/zenoh-plugin-rest/Cargo.toml b/plugins/zenoh-plugin-rest/Cargo.toml index 616b5a5b67..31e1e6d3f4 100644 --- a/plugins/zenoh-plugin-rest/Cargo.toml +++ b/plugins/zenoh-plugin-rest/Cargo.toml @@ -25,7 +25,7 @@ description = "The zenoh REST plugin" [features] default = ["no_mangle"] -no_mangle = ["zenoh-plugin-trait/no_mangle"] +no_mangle = [] [lib] name = "zenoh_plugin_rest" diff --git a/plugins/zenoh-plugin-storage-manager/Cargo.toml b/plugins/zenoh-plugin-storage-manager/Cargo.toml index ce56e18d0e..f03c4bcedf 100644 --- a/plugins/zenoh-plugin-storage-manager/Cargo.toml +++ b/plugins/zenoh-plugin-storage-manager/Cargo.toml @@ -25,7 +25,7 @@ description = "The zenoh storages plugin." [features] default = ["no_mangle"] -no_mangle = ["zenoh-plugin-trait/no_mangle"] +no_mangle = [] [lib] name = "zenoh_plugin_storage_manager" diff --git a/plugins/zenoh-plugin-trait/Cargo.toml b/plugins/zenoh-plugin-trait/Cargo.toml index 362ae942d6..d930437232 100644 --- a/plugins/zenoh-plugin-trait/Cargo.toml +++ b/plugins/zenoh-plugin-trait/Cargo.toml @@ -26,10 +26,6 @@ description = { workspace = true } [lib] name = "zenoh_plugin_trait" -[features] -default = ["no_mangle"] -no_mangle = [] - [dependencies] libloading = { workspace = true } log = { workspace = true } diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index d2f8a32819..70409afb05 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -33,5 +33,5 @@ use zenoh_util::concat_enabled_features; pub const FEATURES: &str = concat_enabled_features!( prefix = "zenoh-plugin-trait", - features = ["default", "no_mangle"] + features = ["default"] ); diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index ce6bf32193..2a883df31a 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -199,41 +199,33 @@ impl PluginVTable { } } -pub use no_mangle::*; -#[cfg(feature = "no_mangle")] -pub mod no_mangle { - /// This macro will add a non-mangled functions which provides plugin version and loads it if feature `no_mangle` is enabled (which it is by default). - #[macro_export] - macro_rules! declare_plugin { - ($ty: path) => { - #[no_mangle] - fn get_plugin_loader_version() -> $crate::PluginLoaderVersion { - $crate::PLUGIN_LOADER_VERSION - } - - #[no_mangle] - fn get_compatibility() -> $crate::Compatibility { - $crate::Compatibility::with_plugin_version::< - <$ty as $crate::Plugin>::StartArgs, - <$ty as $crate::Plugin>::Instance, - $ty, - >() - } - - #[no_mangle] - fn load_plugin() -> $crate::PluginVTable< +/// This macro will add a non-mangled functions which provides plugin version and loads it if feature `no_mangle` is enabled in the destination crate. +#[macro_export] +macro_rules! declare_plugin { + ($ty: path) => { + #[cfg(feature = "no_mangle")] + #[no_mangle] + fn get_plugin_loader_version() -> $crate::PluginLoaderVersion { + $crate::PLUGIN_LOADER_VERSION + } + + #[cfg(feature = "no_mangle")] + #[no_mangle] + fn get_compatibility() -> $crate::Compatibility { + $crate::Compatibility::with_plugin_version::< <$ty as $crate::Plugin>::StartArgs, <$ty as $crate::Plugin>::Instance, - > { - $crate::PluginVTable::new::<$ty>() - } - }; - } -} -#[cfg(not(feature = "no_mangle"))] -pub mod no_mangle { - #[macro_export] - macro_rules! declare_plugin { - ($ty: path) => {}; - } -} + $ty, + >() + } + + #[cfg(feature = "no_mangle")] + #[no_mangle] + fn load_plugin() -> $crate::PluginVTable< + <$ty as $crate::Plugin>::StartArgs, + <$ty as $crate::Plugin>::Instance, + > { + $crate::PluginVTable::new::<$ty>() + } + }; +} \ No newline at end of file From 51d5eb381b5954cbdec6c4bcb9e1b1d5aa3f934a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 5 Dec 2023 11:47:38 +0100 Subject: [PATCH 074/106] no full failure due to one storage --- .../zenoh-plugin-storage-manager/src/lib.rs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 1767201300..d568037e18 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -38,6 +38,7 @@ use zenoh_backend_traits::config::VolumeConfig; use zenoh_backend_traits::VolumePlugin; use zenoh_core::zlock; use zenoh_plugin_trait::Plugin; +use zenoh_plugin_trait::PluginConditionSetter; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginReport; use zenoh_plugin_trait::PluginStatusRec; @@ -111,11 +112,14 @@ impl StorageRuntimeInner { .map(|search_dirs| LibLoader::new(&search_dirs, false)) .unwrap_or_default(); - let session = Arc::new(zenoh::init(runtime.clone()).res_sync().unwrap()); - let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX) .declare_static_plugin::(); + + let session = Arc::new(zenoh::init(runtime.clone()).res_sync()?); + + // After this moment result should be only Ok. Failure of loading of one voulme or storage should not affect others. + let mut new_self = StorageRuntimeInner { name, runtime, @@ -123,19 +127,21 @@ impl StorageRuntimeInner { storages: Default::default(), plugins_manager, }; - new_self.spawn_volume(VolumeConfig { + let _ = new_self.spawn_volume(VolumeConfig { name: MEMORY_BACKEND_NAME.into(), backend: None, paths: None, required: false, rest: Default::default(), - })?; - new_self.update( - volumes - .into_iter() - .map(ConfigDiff::AddVolume) - .chain(storages.into_iter().map(ConfigDiff::AddStorage)), - )?; + }); + for volume in volumes { + let _ = new_self + .spawn_volume(volume); + } + for storage in storages { + let _ = new_self + .spawn_storage(storage); + } Ok(new_self) } fn update>(&mut self, diffs: I) -> ZResult<()> { From c976e1c57174643bbd3a833a45b19276ebdb0737 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 5 Dec 2023 14:59:25 +0000 Subject: [PATCH 075/106] config for testing plugins, error s logging --- DEFAULT_CONFIG.json5 | 24 ++++++++-------- plugin_test_config.json5 | 28 +++++++++++++++++++ .../zenoh-plugin-storage-manager/src/lib.rs | 12 ++++---- 3 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 plugin_test_config.json5 diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index fd3d08d942..4321c3fcc7 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -407,17 +407,17 @@ // }, /// Plugin configuration example using `__config__` property - plugins: { - rest: { - __config__: "./plugins/zenoh-plugin-rest/config.json5", - }, - storage_manager: { - __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - }, - not_found: { - }, - example: { - }, - }, + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // }, + // not_found: { + // }, + // example: { + // }, + // }, } diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 new file mode 100644 index 0000000000..3c4b98c06b --- /dev/null +++ b/plugin_test_config.json5 @@ -0,0 +1,28 @@ +{ + "plugins": { + "rest": { + "http_port": 8080, + }, + "storage_manager": { + "volumes": { + "example": { + "__path__": ["target/debug/libzenoh_backend_example.so","target/debug/libzenoh_backend_example.dylib"], + } + }, + "storages": { + "memory": { + "volume": "memory", + "key_expr": "demo/memory/**" + }, + "example": { + "volume": "example", + "key_expr": "demo/example/**" + }, + } + }, + "not_found": { + }, + "example": { + }, + } +} diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index d568037e18..880b794a68 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -127,20 +127,20 @@ impl StorageRuntimeInner { storages: Default::default(), plugins_manager, }; - let _ = new_self.spawn_volume(VolumeConfig { + new_self.spawn_volume(VolumeConfig { name: MEMORY_BACKEND_NAME.into(), backend: None, paths: None, required: false, rest: Default::default(), - }); + }).map_or_else(|e| log::error!("Cannot spawn memory volume: {}", e), |_| ()); for volume in volumes { - let _ = new_self - .spawn_volume(volume); + new_self + .spawn_volume(volume).map_or_else(|e| log::error!("Cannot spawn volume: {}", e), |_| ()); } for storage in storages { - let _ = new_self - .spawn_storage(storage); + new_self + .spawn_storage(storage).map_or_else(|e| log::error!("Cannot spawn storage: {}", e), |_| ()); } Ok(new_self) } From 03d426dc50da4303b075c0f79d080799cfc38da0 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 5 Dec 2023 15:16:49 +0000 Subject: [PATCH 076/106] no_mangle in example --- plugins/example-storage-plugin/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/example-storage-plugin/Cargo.toml b/plugins/example-storage-plugin/Cargo.toml index 37465b5f87..b9d56615d4 100644 --- a/plugins/example-storage-plugin/Cargo.toml +++ b/plugins/example-storage-plugin/Cargo.toml @@ -18,6 +18,10 @@ version = { workspace = true } authors = { workspace = true } edition = { workspace = true } +[features] +default = ["no_mangle"] +no_mangle = [] + [lib] name = "zenoh_backend_example" # This crate type will make `cargo` output a dynamic library instead of a rust static library From 3d7c61403865ea2eae646db9c2c2b6a551c328cb Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 5 Dec 2023 15:24:23 +0000 Subject: [PATCH 077/106] compile fixes --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 1 - zenoh/src/net/routing/face.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 880b794a68..928aaeac18 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -38,7 +38,6 @@ use zenoh_backend_traits::config::VolumeConfig; use zenoh_backend_traits::VolumePlugin; use zenoh_core::zlock; use zenoh_plugin_trait::Plugin; -use zenoh_plugin_trait::PluginConditionSetter; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginReport; use zenoh_plugin_trait::PluginStatusRec; diff --git a/zenoh/src/net/routing/face.rs b/zenoh/src/net/routing/face.rs index 7616420ec8..90946527ee 100644 --- a/zenoh/src/net/routing/face.rs +++ b/zenoh/src/net/routing/face.rs @@ -81,7 +81,7 @@ impl FaceState { }) } - #[cfg(feature = "unstable")] + #[allow(dead_code)] #[inline] pub fn is_local(&self) -> bool { self.local From 536d808678e3bed0aaec39063b7d70978db8b6d0 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 5 Dec 2023 15:47:47 +0000 Subject: [PATCH 078/106] dds plugin tested --- plugin_test_config.json5 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 index 3c4b98c06b..e5575c905d 100644 --- a/plugin_test_config.json5 +++ b/plugin_test_config.json5 @@ -24,5 +24,8 @@ }, "example": { }, + "dds": { + "__path__": ["../zenoh-plugin-dds/target/debug/libzenoh_plugin_dds.so","../zenoh-plugin-dds/target/debug/libzenoh_plugin_dds.dylib"], + } } } From 296142b4c2fe647de413b7283b8c213c37f89bd2 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 5 Dec 2023 16:01:52 +0000 Subject: [PATCH 079/106] cargo fmt --- plugins/zenoh-backend-traits/src/lib.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 23 +++++++++++-------- plugins/zenoh-plugin-trait/src/lib.rs | 6 ++--- plugins/zenoh-plugin-trait/src/vtable.rs | 2 +- zenoh/src/net/runtime/adminspace.rs | 6 ++--- zenoh/src/plugins/sealed.rs | 5 ++-- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index b7b7c9220a..ec42a5b581 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -15,7 +15,7 @@ //! ⚠️ WARNING ⚠️ //! //! TODO: The example is outdated, rewrite it -//! +//! //! This crate should be considered unstable, as in we might change the APIs anytime. //! //! This crate provides the traits to be implemented by a zenoh backend library: diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 928aaeac18..41dd2ba627 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -114,7 +114,6 @@ impl StorageRuntimeInner { let plugins_manager = PluginsManager::dynamic(lib_loader.clone(), BACKEND_LIB_PREFIX) .declare_static_plugin::(); - let session = Arc::new(zenoh::init(runtime.clone()).res_sync()?); // After this moment result should be only Ok. Failure of loading of one voulme or storage should not affect others. @@ -126,20 +125,24 @@ impl StorageRuntimeInner { storages: Default::default(), plugins_manager, }; - new_self.spawn_volume(VolumeConfig { - name: MEMORY_BACKEND_NAME.into(), - backend: None, - paths: None, - required: false, - rest: Default::default(), - }).map_or_else(|e| log::error!("Cannot spawn memory volume: {}", e), |_| ()); + new_self + .spawn_volume(VolumeConfig { + name: MEMORY_BACKEND_NAME.into(), + backend: None, + paths: None, + required: false, + rest: Default::default(), + }) + .map_or_else(|e| log::error!("Cannot spawn memory volume: {}", e), |_| ()); for volume in volumes { new_self - .spawn_volume(volume).map_or_else(|e| log::error!("Cannot spawn volume: {}", e), |_| ()); + .spawn_volume(volume) + .map_or_else(|e| log::error!("Cannot spawn volume: {}", e), |_| ()); } for storage in storages { new_self - .spawn_storage(storage).map_or_else(|e| log::error!("Cannot spawn storage: {}", e), |_| ()); + .spawn_storage(storage) + .map_or_else(|e| log::error!("Cannot spawn storage: {}", e), |_| ()); } Ok(new_self) } diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 70409afb05..b3e91c2395 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -31,7 +31,5 @@ pub use plugin::{ pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; use zenoh_util::concat_enabled_features; -pub const FEATURES: &str = concat_enabled_features!( - prefix = "zenoh-plugin-trait", - features = ["default"] -); +pub const FEATURES: &str = + concat_enabled_features!(prefix = "zenoh-plugin-trait", features = ["default"]); diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 2a883df31a..d4e51a3ade 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -228,4 +228,4 @@ macro_rules! declare_plugin { $crate::PluginVTable::new::<$ty>() } }; -} \ No newline at end of file +} diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 73604e0e81..dd7f3adc7a 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -21,15 +21,15 @@ use crate::value::Value; use async_std::task; use log::{error, trace}; use serde_json::json; -use zenoh_plugin_trait::{PluginControl, PluginStatus}; -use zenoh_protocol::core::key_expr::keyexpr; use std::collections::HashMap; use std::convert::TryFrom; use std::convert::TryInto; use std::sync::Arc; use std::sync::Mutex; use zenoh_buffers::buffer::SplitBuffer; -use zenoh_config::{ValidatedMap, ConfigValidator}; +use zenoh_config::{ConfigValidator, ValidatedMap}; +use zenoh_plugin_trait::{PluginControl, PluginStatus}; +use zenoh_protocol::core::key_expr::keyexpr; use zenoh_protocol::{ core::{key_expr::OwnedKeyExpr, ExprId, KnownEncoding, WireExpr, ZenohId, EMPTY_EXPR_ID}, network::{ diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 573c18ab60..7e790270e0 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -19,13 +19,14 @@ pub use crate::runtime::Runtime; pub use crate::Result as ZResult; use zenoh_core::zconfigurable; -use zenoh_plugin_trait::{Plugin, PluginControl, PluginInstance, PluginReport, PluginStatusRec, PluginStructVersion}; +use zenoh_plugin_trait::{ + Plugin, PluginControl, PluginInstance, PluginReport, PluginStatusRec, PluginStructVersion, +}; use zenoh_protocol::core::key_expr::keyexpr; zconfigurable! { pub static ref PLUGIN_PREFIX: String = "zenoh_plugin_".to_string(); } - /// Zenoh plugins should implement this trait to ensure type-safety, even if the starting arguments and expected plugin types change in a future release. pub trait ZenohPlugin: Plugin {} From 486ed78d03846b91a6dda4e86779a402f0d047e5 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Jan 2024 16:22:00 +0100 Subject: [PATCH 080/106] removed reexport of ZResult and Runtime types from plugin mod --- Cargo.lock | 2 +- zenoh/src/plugins/sealed.rs | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17c38bc575..c115f80499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4986,7 +4986,7 @@ version = "0.11.0-dev" dependencies = [ "async-std", "async-trait", - "clap 3.2.25", + "clap", "env_logger", "futures", "log", diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 7e790270e0..8adbde4162 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -14,27 +14,24 @@ //! `zenohd`'s plugin system. For more details, consult the [detailed documentation](https://github.com/eclipse-zenoh/roadmap/blob/main/rfcs/ALL/Plugins/Zenoh%20Plugins.md). -use crate::prelude::Selector; -pub use crate::runtime::Runtime; -pub use crate::Result as ZResult; +use crate::{prelude::Selector, runtime::Runtime}; use zenoh_core::zconfigurable; use zenoh_plugin_trait::{ Plugin, PluginControl, PluginInstance, PluginReport, PluginStatusRec, PluginStructVersion, }; use zenoh_protocol::core::key_expr::keyexpr; +use zenoh_result::ZResult; zconfigurable! { pub static ref PLUGIN_PREFIX: String = "zenoh_plugin_".to_string(); } -/// Zenoh plugins should implement this trait to ensure type-safety, even if the starting arguments and expected plugin types change in a future release. -pub trait ZenohPlugin: Plugin {} - -/// A zenoh plugin receives a reference to a value of this type when started. -pub type StartArgs = Runtime; /// A zenoh plugin, when started, must return this type. pub type RunningPlugin = Box; +/// Zenoh plugins should implement this trait to ensure type-safety, even if the starting arguments and expected plugin types change in a future release. +pub trait ZenohPlugin: Plugin {} + impl PluginStructVersion for RunningPlugin { fn struct_version() -> u64 { 1 @@ -98,4 +95,4 @@ pub trait RunningPluginTrait: Send + Sync + PluginControl { } /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. -pub type PluginsManager = zenoh_plugin_trait::PluginsManager; +pub type PluginsManager = zenoh_plugin_trait::PluginsManager; From c960dc483dfe0967d4fc97625c2cb8fb3e51c978 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Jan 2024 17:03:26 +0100 Subject: [PATCH 081/106] doc comments updated --- plugins/zenoh-plugin-trait/src/plugin.rs | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 21a978a26c..cc14d1d37d 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -28,7 +28,7 @@ pub enum PluginState { } /// The severity level of a plugin report messages -/// - Normal: the message(s) is just a notification +/// - Normal: the message(s) are just notifications /// - Warning: at least one warning is reported /// - Error: at least one error is reported #[derive(Copy, Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, PartialOrd, Ord)] @@ -39,7 +39,7 @@ pub enum PluginReportLevel { Error, } -/// Allow to use `|=` operator to update the severity level of a report +/// Allow using the `|=` operator to update the severity level of a report impl BitOrAssign for PluginReportLevel { fn bitor_assign(&mut self, rhs: Self) { if *self < rhs { @@ -49,7 +49,7 @@ impl BitOrAssign for PluginReportLevel { } /// A plugin report contains a severity level and a list of messages -/// describing the plugin's situation (for Declared state - dynamic library loading errors, for Loaded state - plugin start errors, etc) +/// describing the plugin's situation (for the Declared state - dynamic library loading errors, for the Loaded state - plugin start errors, etc) #[derive(Clone, Debug, PartialEq, Eq, Serialize, Default, Deserialize)] pub struct PluginReport { level: PluginReportLevel, @@ -57,22 +57,22 @@ pub struct PluginReport { messages: Vec>, } -/// Trait allowing to get all information about the plugin +/// Trait allowing getting all information about the plugin pub trait PluginStatus { - /// Returns name of the plugin + /// Returns the name of the plugin fn name(&self) -> &str; - /// Returns version of the loaded plugin (usually the version of the plugin's crate) + /// Returns the version of the loaded plugin (usually the version of the plugin's crate) fn version(&self) -> Option<&str>; - /// Returns path of the loaded plugin + /// Returns the path of the loaded plugin fn path(&self) -> &str; /// Returns the plugin's state (Declared, Loaded, Started) fn state(&self) -> PluginState; /// Returns the plugin's current report: a list of messages and the severity level - /// When status is changed, report is cleared + /// When the status is changed, the report is cleared fn report(&self) -> PluginReport; } -/// The structure which contains all information about the plugin status in single cloneable structure +/// The structure which contains all information about the plugin status in a single cloneable structure #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PluginStatusRec<'a> { pub name: Cow<'a, str>, @@ -102,7 +102,7 @@ impl PluginStatus for PluginStatusRec<'_> { } impl<'a> PluginStatusRec<'a> { - /// Construst status fructure from the getter interface + /// Construct the status structure from the getter interface pub fn new(plugin: &'a T) -> Self { Self { name: Cow::Borrowed(plugin.name()), @@ -112,7 +112,7 @@ impl<'a> PluginStatusRec<'a> { report: plugin.report(), } } - /// Convert status structure to owned version + /// Convert the status structure to the owned version pub fn into_owned(self) -> PluginStatusRec<'static> { PluginStatusRec { name: Cow::Owned(self.name.into_owned()), @@ -130,22 +130,26 @@ impl<'a> PluginStatusRec<'a> { } } +/// This trait allows getting information about the plugin status and the status of its subplugins, if any. pub trait PluginControl { + /// Returns the current state of the running plugin. By default, the state is `PluginReportLevel::Normal` and the list of messages is empty. + /// This can be overridden by the plugin implementation if the plugin is able to report its status: no connection to the database, etc. fn report(&self) -> PluginReport { PluginReport::default() } - /// Collect information of sub-plugins matching `_names` keyexpr + /// Collects information of sub-plugins matching the `_names` key expression. The information is richer than the one returned by `report()`: it contains external information about the running plugin, such as its name, path on disk, load status, etc. + /// Returns an empty list by default. fn plugins_status(&self, _names: &keyexpr) -> Vec { Vec::new() } } pub trait PluginStructVersion { - /// The version of the structure implementing this trait. After any channge in the structure or it's dependencies - /// whcich may affect the ABI, this version should be incremented. + /// The version of the structure implementing this trait. After any change in the structure or its dependencies + /// which may affect the ABI, this version should be incremented. fn struct_version() -> u64; /// The features enabled during compilation of the structure implementing this trait. - /// Different features between the plugin and the host may cuase ABI incompatibility even if the structure version is the same. + /// Different features between the plugin and the host may cause ABI incompatibility even if the structure version is the same. /// Use `concat_enabled_features!` to generate this string fn struct_features() -> &'static str; } From db01409d91b40f90e7aae1e436e1a31463663162 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 10 Jan 2024 14:15:37 +0100 Subject: [PATCH 082/106] renaming, removed unused type --- plugins/example-storage-plugin/src/lib.rs | 4 ++-- plugins/zenoh-backend-traits/src/lib.rs | 12 ++++-------- .../zenoh-plugin-storage-manager/src/backends_mgt.rs | 4 ++-- plugins/zenoh-plugin-storage-manager/src/lib.rs | 4 ++-- .../src/memory_backend/mod.rs | 4 ++-- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index fac7fbf295..3bcce23892 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -22,7 +22,7 @@ use zenoh::{prelude::OwnedKeyExpr, sample::Sample, time::Timestamp, value::Value use zenoh_backend_traits::{ config::{StorageConfig, VolumeConfig}, Capability, History, Persistence, Storage, StorageInsertionResult, StoredData, Volume, - VolumePlugin, + VolumeInstance, }; use zenoh_plugin_trait::Plugin; use zenoh_result::ZResult; @@ -31,7 +31,7 @@ zenoh_plugin_trait::declare_plugin!(ExampleBackend); impl Plugin for ExampleBackend { type StartArgs = VolumeConfig; - type Instance = VolumePlugin; + type Instance = VolumeInstance; fn start(_name: &str, _args: &Self::StartArgs) -> ZResult { let volume = ExampleBackend {}; Ok(Box::new(volume)) diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index ec42a5b581..26a820bd3f 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -183,10 +183,6 @@ pub enum History { All, } -/// Signature of the `create_volume` operation to be implemented in the library as an entrypoint. -pub const CREATE_VOLUME_FN_NAME: &[u8] = b"create_volume"; -pub type CreateVolume = fn(VolumeConfig) -> ZResult>; - /// pub enum StorageInsertionResult { Outdated, @@ -224,9 +220,9 @@ pub trait Volume: Send + Sync { fn outgoing_data_interceptor(&self) -> Option Sample + Send + Sync>>; } -pub type VolumePlugin = Box; +pub type VolumeInstance = Box; -impl PluginStructVersion for VolumePlugin { +impl PluginStructVersion for VolumeInstance { fn struct_version() -> u64 { 1 } @@ -235,13 +231,13 @@ impl PluginStructVersion for VolumePlugin { } } -impl PluginControl for VolumePlugin { +impl PluginControl for VolumeInstance { fn plugins_status(&self, _names: &zenoh::prelude::keyexpr) -> Vec { Vec::new() } } -impl PluginInstance for VolumePlugin {} +impl PluginInstance for VolumeInstance {} /// Trait to be implemented by a Storage. #[async_trait] diff --git a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs index 9f29803fe3..85c4ebf48d 100644 --- a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs +++ b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs @@ -17,7 +17,7 @@ use std::sync::Arc; use zenoh::prelude::r#async::*; use zenoh::Session; use zenoh_backend_traits::config::StorageConfig; -use zenoh_backend_traits::{Capability, VolumePlugin}; +use zenoh_backend_traits::{Capability, VolumeInstance}; use zenoh_result::ZResult; pub struct StoreIntercept { @@ -30,7 +30,7 @@ pub struct StoreIntercept { pub(crate) async fn create_and_start_storage( admin_key: String, config: StorageConfig, - backend: &VolumePlugin, + backend: &VolumeInstance, in_interceptor: Option Sample + Send + Sync>>, out_interceptor: Option Sample + Send + Sync>>, zenoh: Arc, diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 41dd2ba627..b1726c731d 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -35,7 +35,7 @@ use zenoh_backend_traits::config::ConfigDiff; use zenoh_backend_traits::config::PluginConfig; use zenoh_backend_traits::config::StorageConfig; use zenoh_backend_traits::config::VolumeConfig; -use zenoh_backend_traits::VolumePlugin; +use zenoh_backend_traits::VolumeInstance; use zenoh_core::zlock; use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; @@ -77,7 +77,7 @@ impl Plugin for StoragesPlugin { } } -type PluginsManager = zenoh_plugin_trait::PluginsManager; +type PluginsManager = zenoh_plugin_trait::PluginsManager; struct StorageRuntime(Arc>); struct StorageRuntimeInner { diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index c9d0509554..de6f2eed73 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -30,12 +30,12 @@ pub struct MemoryBackend { impl Plugin for MemoryBackend { type StartArgs = VolumeConfig; - type Instance = VolumePlugin; + type Instance = VolumeInstance; const DEFAULT_NAME: &'static str = MEMORY_BACKEND_NAME; const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); - fn start(_: &str, args: &VolumeConfig) -> ZResult { + fn start(_: &str, args: &VolumeConfig) -> ZResult { Ok(Box::new(MemoryBackend { config: args.clone(), })) From 765018566e981ba553aeafada8bef3897c39c0e1 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 10 Jan 2024 15:12:49 +0100 Subject: [PATCH 083/106] constant version string --- Cargo.lock | 2 +- plugins/zenoh-backend-traits/src/lib.rs | 4 ++-- plugins/zenoh-plugin-storage-manager/Cargo.toml | 2 +- plugins/zenoh-plugin-storage-manager/src/lib.rs | 16 +++++++++++----- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c115f80499..0748b16d7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5007,6 +5007,7 @@ dependencies = [ "async-std", "async-trait", "clap", + "const_format", "crc", "derive-new", "env_logger", @@ -5014,7 +5015,6 @@ dependencies = [ "futures", "git-version", "jsonschema", - "lazy_static", "libloading", "log", "rustc_version 0.4.0", diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 26a820bd3f..16aad432d7 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -145,10 +145,10 @@ use zenoh_plugin_trait::{PluginControl, PluginInstance, PluginStatusRec, PluginS use zenoh_util::concat_enabled_features; pub mod config; -use config::{StorageConfig, VolumeConfig}; +use config::StorageConfig; // No features are actually used in this crate, but this dummy list allows to demonstrate how to combine feature lists -// from multiple crates. See implementation of `CompatibilityVersion::features()` for more `VolumePlugin` and `VolumeConfig` types +// from multiple crates. See impl `PluginStructVersion` for `VolumeConfig` below. const FEATURES: &str = concat_enabled_features!(prefix = "zenoh-backend-traits", features = ["default"]); diff --git a/plugins/zenoh-plugin-storage-manager/Cargo.toml b/plugins/zenoh-plugin-storage-manager/Cargo.toml index f03c4bcedf..43b021cbea 100644 --- a/plugins/zenoh-plugin-storage-manager/Cargo.toml +++ b/plugins/zenoh-plugin-storage-manager/Cargo.toml @@ -36,12 +36,12 @@ async-std = { workspace = true, features = ["default"] } async-trait = { workspace = true } clap = { workspace = true } crc = { workspace = true } +const_format = { workspace = true } derive-new = { workspace = true } env_logger = { workspace = true } flume = { workspace = true } futures = { workspace = true } git-version = { workspace = true } -lazy_static = { workspace = true } libloading = { workspace = true } log = { workspace = true } serde = { workspace = true, features = ["default"] } diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index b1726c731d..f5749199b8 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -20,10 +20,12 @@ #![recursion_limit = "512"] use async_std::task; +use const_format::concatcp; use flume::Sender; use memory_backend::MemoryBackend; use std::collections::HashMap; use std::convert::TryFrom; +use std::env; use std::sync::Arc; use std::sync::Mutex; use storages_mgt::StorageMessage; @@ -51,23 +53,27 @@ mod replica; mod storages_mgt; const GIT_VERSION: &str = git_version::git_version!(prefix = "v", cargo_prefix = "v"); -lazy_static::lazy_static! { - static ref LONG_VERSION: String = format!("{} built with {}", GIT_VERSION, env!("RUSTC_VERSION")); -} +const LONG_VERSION: &str = concatcp!{ + env!("CARGO_PKG_VERSION"), + " ", + GIT_VERSION, + " built with ", + env!("RUSTC_VERSION") +}; zenoh_plugin_trait::declare_plugin!(StoragesPlugin); pub struct StoragesPlugin {} impl ZenohPlugin for StoragesPlugin {} impl Plugin for StoragesPlugin { const DEFAULT_NAME: &'static str = "storage_manager"; - const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); + const PLUGIN_VERSION: &'static str = LONG_VERSION; type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { std::mem::drop(env_logger::try_init()); - log::debug!("StorageManager plugin {}", LONG_VERSION.as_str()); + log::debug!("StorageManager plugin {}", LONG_VERSION); let config = { PluginConfig::try_from((name, runtime.config().lock().plugin(name).unwrap())) }?; Ok(Box::new(StorageRuntime::from(StorageRuntimeInner::new( From 456d48b9a77168e4daf0f94f88f0194badfb1f89 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 10 Jan 2024 15:14:35 +0100 Subject: [PATCH 084/106] macro simplified --- commons/zenoh-util/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons/zenoh-util/src/lib.rs b/commons/zenoh-util/src/lib.rs index 7e02096ebb..91ca41846d 100644 --- a/commons/zenoh-util/src/lib.rs +++ b/commons/zenoh-util/src/lib.rs @@ -28,7 +28,7 @@ macro_rules! concat_enabled_features { { use const_format::concatcp; concatcp!("" $(, - if cfg!(feature = $feature) { concatcp!(" ", concatcp!($prefix, "/", $feature)) } else { "" } + if cfg!(feature = $feature) { concatcp!(" ", $prefix, "/", $feature) } else { "" } )*) } }; From 8c883412838c166a3e964ee9b4bae3fba694b748 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 10 Jan 2024 17:55:41 +0100 Subject: [PATCH 085/106] doc updated, version macro added --- Cargo.lock | 5 +++++ commons/zenoh-util/src/lib.rs | 2 +- plugins/example-plugin/Cargo.toml | 2 ++ plugins/example-plugin/src/lib.rs | 4 ++-- plugins/example-storage-plugin/Cargo.toml | 2 ++ plugins/example-storage-plugin/src/lib.rs | 4 ++-- plugins/zenoh-plugin-rest/Cargo.toml | 1 + plugins/zenoh-plugin-rest/src/lib.rs | 4 ++-- plugins/zenoh-plugin-storage-manager/src/lib.rs | 17 ++++------------- plugins/zenoh-plugin-trait/src/lib.rs | 14 ++++++++++++++ plugins/zenoh-plugin-trait/src/plugin.rs | 16 +++++++++++++++- 11 files changed, 50 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0748b16d7e..833adf3190 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4942,8 +4942,10 @@ version = "0.11.0-dev" dependencies = [ "async-std", "clap", + "const_format", "env_logger", "futures", + "git-version", "log", "serde_json", "zenoh", @@ -4961,6 +4963,7 @@ dependencies = [ "async-std", "base64 0.21.4", "clap", + "const_format", "env_logger", "flume", "futures", @@ -4987,8 +4990,10 @@ dependencies = [ "async-std", "async-trait", "clap", + "const_format", "env_logger", "futures", + "git-version", "log", "serde_json", "zenoh", diff --git a/commons/zenoh-util/src/lib.rs b/commons/zenoh-util/src/lib.rs index 91ca41846d..7e02096ebb 100644 --- a/commons/zenoh-util/src/lib.rs +++ b/commons/zenoh-util/src/lib.rs @@ -28,7 +28,7 @@ macro_rules! concat_enabled_features { { use const_format::concatcp; concatcp!("" $(, - if cfg!(feature = $feature) { concatcp!(" ", $prefix, "/", $feature) } else { "" } + if cfg!(feature = $feature) { concatcp!(" ", concatcp!($prefix, "/", $feature)) } else { "" } )*) } }; diff --git a/plugins/example-plugin/Cargo.toml b/plugins/example-plugin/Cargo.toml index 6091635191..360df96c3a 100644 --- a/plugins/example-plugin/Cargo.toml +++ b/plugins/example-plugin/Cargo.toml @@ -35,9 +35,11 @@ crate-type = ["cdylib"] [dependencies] async-std = { workspace = true, features = ["default"] } +const_format = { workspace = true } clap = { workspace = true } env_logger = { workspace = true } futures = { workspace = true } +git-version = { workspace = true } log = { workspace = true } serde_json = { workspace = true } zenoh = { workspace = true } diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 1a00e98e08..e930bb148e 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -25,7 +25,7 @@ use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; -use zenoh_plugin_trait::{Plugin, PluginControl}; +use zenoh_plugin_trait::{Plugin, PluginControl, plugin_version}; use zenoh_result::{bail, ZResult}; // The struct implementing the ZenohPlugin and ZenohPlugin traits @@ -45,7 +45,7 @@ impl Plugin for ExamplePlugin { // A mandatory const to define, in case of the plugin is built as a standalone executable const DEFAULT_NAME: &'static str = "example"; - const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); + const PLUGIN_VERSION: &'static str = plugin_version!(); // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { diff --git a/plugins/example-storage-plugin/Cargo.toml b/plugins/example-storage-plugin/Cargo.toml index b9d56615d4..0e532691c8 100644 --- a/plugins/example-storage-plugin/Cargo.toml +++ b/plugins/example-storage-plugin/Cargo.toml @@ -30,8 +30,10 @@ crate-type = ["cdylib"] [dependencies] async-std = { workspace = true, features = ["default"] } clap = { workspace = true } +const_format = { workspace = true } env_logger = { workspace = true } futures = { workspace = true } +git-version = { workspace = true } log = { workspace = true } serde_json = { workspace = true } zenoh = { workspace = true } diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index 3bcce23892..27d84abe08 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -24,7 +24,7 @@ use zenoh_backend_traits::{ Capability, History, Persistence, Storage, StorageInsertionResult, StoredData, Volume, VolumeInstance, }; -use zenoh_plugin_trait::Plugin; +use zenoh_plugin_trait::{Plugin, plugin_version}; use zenoh_result::ZResult; zenoh_plugin_trait::declare_plugin!(ExampleBackend); @@ -38,7 +38,7 @@ impl Plugin for ExampleBackend { } const DEFAULT_NAME: &'static str = "example_backend"; - const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); + const PLUGIN_VERSION: &'static str = plugin_version!(); } pub struct ExampleBackend {} diff --git a/plugins/zenoh-plugin-rest/Cargo.toml b/plugins/zenoh-plugin-rest/Cargo.toml index 31e1e6d3f4..837c157c25 100644 --- a/plugins/zenoh-plugin-rest/Cargo.toml +++ b/plugins/zenoh-plugin-rest/Cargo.toml @@ -36,6 +36,7 @@ anyhow = { workspace = true, features = ["default"] } async-std = { workspace = true, features = ["default"] } base64 = { workspace = true } clap = { workspace = true } +const_format = { workspace = true } env_logger = { workspace = true } flume = { workspace = true } futures = { workspace = true } diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index fb9fb17b49..182878765e 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -34,7 +34,7 @@ use zenoh::query::{QueryConsolidation, Reply}; use zenoh::runtime::Runtime; use zenoh::selector::TIME_RANGE_KEY; use zenoh::Session; -use zenoh_plugin_trait::{Plugin, PluginControl}; +use zenoh_plugin_trait::{Plugin, PluginControl, plugin_version}; use zenoh_result::{bail, zerror, ZResult}; mod config; @@ -218,7 +218,7 @@ impl Plugin for RestPlugin { type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; const DEFAULT_NAME: &'static str = "rest"; - const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); + const PLUGIN_VERSION: &'static str = plugin_version!(); fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { // Try to initiate login. diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index f5749199b8..2e0d68b347 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -20,9 +20,9 @@ #![recursion_limit = "512"] use async_std::task; -use const_format::concatcp; use flume::Sender; use memory_backend::MemoryBackend; +use zenoh_plugin_trait::plugin_version; use std::collections::HashMap; use std::convert::TryFrom; use std::env; @@ -52,28 +52,19 @@ mod memory_backend; mod replica; mod storages_mgt; -const GIT_VERSION: &str = git_version::git_version!(prefix = "v", cargo_prefix = "v"); -const LONG_VERSION: &str = concatcp!{ - env!("CARGO_PKG_VERSION"), - " ", - GIT_VERSION, - " built with ", - env!("RUSTC_VERSION") -}; - zenoh_plugin_trait::declare_plugin!(StoragesPlugin); pub struct StoragesPlugin {} impl ZenohPlugin for StoragesPlugin {} impl Plugin for StoragesPlugin { const DEFAULT_NAME: &'static str = "storage_manager"; - const PLUGIN_VERSION: &'static str = LONG_VERSION; + const PLUGIN_VERSION: &'static str = plugin_version!(); type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { std::mem::drop(env_logger::try_init()); - log::debug!("StorageManager plugin {}", LONG_VERSION); + log::debug!("StorageManager plugin {}", Self::PLUGIN_VERSION); let config = { PluginConfig::try_from((name, runtime.config().lock().plugin(name).unwrap())) }?; Ok(Box::new(StorageRuntime::from(StorageRuntimeInner::new( @@ -304,7 +295,7 @@ impl RunningPluginTrait for StorageRuntime { { responses.push(zenoh::plugins::Response::new( key.clone(), - GIT_VERSION.into(), + StoragesPlugin::PLUGIN_VERSION.into(), )) } }); diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index b3e91c2395..489eb869de 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -19,6 +19,20 @@ //! If building a plugin for [`zenohd`](https://crates.io/crates/zenoh), you should use the types exported in [`zenoh::plugins`](https://docs.rs/zenoh/latest/zenoh/plugins) to fill [`Plugin`]'s associated types. //! To check your plugin typing for `zenohd`, have your plugin implement [`zenoh::plugins::ZenohPlugin`](https://docs.rs/zenoh/latest/zenoh/plugins/struct.ZenohPlugin) //! +//! Plugin is a struct which implements the [`Plugin`] trait. This trait has two associated types: +//! - `StartArgs`: the type of the arguments passed to the plugin's [`start`](Plugin::start) function. +//! - `Instance`: the type of the plugin's instance. +//! +//! The actual work of the plugin is performed by the instance, which is created by the [`start`](Plugin::start) function. +//! +//! Plugins are loaded, started and stopped by [`PluginsManager`](crate::manager::PluginsManager). Stopping pluign is just dropping it's instance. +//! +//! Plugins can be static and dynamic. +//! +//! Static plugin is just a type which implements [`Plugin`] trait. It can be added to [`PluginsManager`](crate::manager::PluginsManager) by [`PluginsManager::add_static_plugin`](crate::manager::PluginsManager::add_static_plugin) method. +//! +//! Dynamic pluign is a shared library which exports set of C-repr (unmangled) functions which allows to check plugin compatibility and create plugin instance. These functiuons are defined automatically by [`declare_plugin`](crate::declare_plugin) macro. +//! mod manager; mod plugin; mod vtable; diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index cc14d1d37d..0e2bee5cfd 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -158,17 +158,31 @@ pub trait PluginStartArgs: PluginStructVersion {} pub trait PluginInstance: PluginStructVersion + PluginControl + Send {} +/// Base plugin trait. The loaded plugin pub trait Plugin: Sized + 'static { type StartArgs: PluginStartArgs; type Instance: PluginInstance; /// Plugins' default name when statically linked. const DEFAULT_NAME: &'static str; - /// Plugin's version. Used only for information purposes. + /// Plugin's version. Used only for information purposes. It's recommended to use [plugin_version!] macro to generate this string. const PLUGIN_VERSION: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure fn start(name: &str, args: &Self::StartArgs) -> ZResult; } +#[macro_export] +macro_rules! plugin_version { + () => { + const_format::concatcp!( + env!("CARGO_PKG_VERSION"), + " ", + git_version::git_version!(prefix = "v", cargo_prefix = "v"), + // " built with ", + // env!("RUSTC_VERSION") // TODO: sometimes RUSTC_VERSION is not available, to be investigated + ) + } +} + impl PluginReport { pub fn new() -> Self { Self::default() From 5d1cd5da213db4414650cba080db6ea4263287fc Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 10 Jan 2024 18:40:55 +0100 Subject: [PATCH 086/106] version simplified, cargo fmt --- plugins/example-plugin/src/lib.rs | 2 +- plugins/example-storage-plugin/src/lib.rs | 2 +- plugins/zenoh-plugin-rest/src/lib.rs | 2 +- plugins/zenoh-plugin-storage-manager/src/lib.rs | 2 +- plugins/zenoh-plugin-trait/src/plugin.rs | 12 +++--------- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index e930bb148e..006a854574 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -25,7 +25,7 @@ use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; -use zenoh_plugin_trait::{Plugin, PluginControl, plugin_version}; +use zenoh_plugin_trait::{plugin_version, Plugin, PluginControl}; use zenoh_result::{bail, ZResult}; // The struct implementing the ZenohPlugin and ZenohPlugin traits diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index 27d84abe08..7757c7f458 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -24,7 +24,7 @@ use zenoh_backend_traits::{ Capability, History, Persistence, Storage, StorageInsertionResult, StoredData, Volume, VolumeInstance, }; -use zenoh_plugin_trait::{Plugin, plugin_version}; +use zenoh_plugin_trait::{plugin_version, Plugin}; use zenoh_result::ZResult; zenoh_plugin_trait::declare_plugin!(ExampleBackend); diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 182878765e..9e70f56add 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -34,7 +34,7 @@ use zenoh::query::{QueryConsolidation, Reply}; use zenoh::runtime::Runtime; use zenoh::selector::TIME_RANGE_KEY; use zenoh::Session; -use zenoh_plugin_trait::{Plugin, PluginControl, plugin_version}; +use zenoh_plugin_trait::{plugin_version, Plugin, PluginControl}; use zenoh_result::{bail, zerror, ZResult}; mod config; diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 2e0d68b347..6068ad36b4 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -22,7 +22,6 @@ use async_std::task; use flume::Sender; use memory_backend::MemoryBackend; -use zenoh_plugin_trait::plugin_version; use std::collections::HashMap; use std::convert::TryFrom; use std::env; @@ -39,6 +38,7 @@ use zenoh_backend_traits::config::StorageConfig; use zenoh_backend_traits::config::VolumeConfig; use zenoh_backend_traits::VolumeInstance; use zenoh_core::zlock; +use zenoh_plugin_trait::plugin_version; use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; use zenoh_plugin_trait::PluginReport; diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 0e2bee5cfd..7efa4c70fa 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -158,7 +158,7 @@ pub trait PluginStartArgs: PluginStructVersion {} pub trait PluginInstance: PluginStructVersion + PluginControl + Send {} -/// Base plugin trait. The loaded plugin +/// Base plugin trait. The loaded plugin pub trait Plugin: Sized + 'static { type StartArgs: PluginStartArgs; type Instance: PluginInstance; @@ -173,14 +173,8 @@ pub trait Plugin: Sized + 'static { #[macro_export] macro_rules! plugin_version { () => { - const_format::concatcp!( - env!("CARGO_PKG_VERSION"), - " ", - git_version::git_version!(prefix = "v", cargo_prefix = "v"), - // " built with ", - // env!("RUSTC_VERSION") // TODO: sometimes RUSTC_VERSION is not available, to be investigated - ) - } + git_version::git_version!(prefix = "v", cargo_prefix = "v") + }; } impl PluginReport { From 0db65a924f067b0f0217e175142ae8a3199eab44 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 10 Jan 2024 19:04:09 +0100 Subject: [PATCH 087/106] unused use removed --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 6068ad36b4..3af9a2887e 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -24,7 +24,6 @@ use flume::Sender; use memory_backend::MemoryBackend; use std::collections::HashMap; use std::convert::TryFrom; -use std::env; use std::sync::Arc; use std::sync::Mutex; use storages_mgt::StorageMessage; From 39f49d8d32ba6a4a586dcc3aa353ae9b52017801 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 12 Jan 2024 18:02:27 +0100 Subject: [PATCH 088/106] long_version field added --- plugins/example-plugin/src/lib.rs | 3 ++- plugins/example-storage-plugin/src/lib.rs | 3 ++- plugins/zenoh-plugin-rest/src/lib.rs | 3 ++- plugins/zenoh-plugin-storage-manager/src/lib.rs | 2 ++ .../src/memory_backend/mod.rs | 5 +++-- plugins/zenoh-plugin-trait/src/manager.rs | 3 +++ .../src/manager/dynamic_plugin.rs | 6 +++++- .../src/manager/static_plugin.rs | 3 +++ plugins/zenoh-plugin-trait/src/plugin.rs | 17 +++++++++++++++++ plugins/zenoh-plugin-trait/src/vtable.rs | 7 +++++++ 10 files changed, 46 insertions(+), 6 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index 006a854574..c37b45399c 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -25,7 +25,7 @@ use zenoh::plugins::{RunningPluginTrait, ZenohPlugin}; use zenoh::prelude::r#async::*; use zenoh::runtime::Runtime; use zenoh_core::zlock; -use zenoh_plugin_trait::{plugin_version, Plugin, PluginControl}; +use zenoh_plugin_trait::{plugin_long_version, plugin_version, Plugin, PluginControl}; use zenoh_result::{bail, ZResult}; // The struct implementing the ZenohPlugin and ZenohPlugin traits @@ -46,6 +46,7 @@ impl Plugin for ExamplePlugin { // A mandatory const to define, in case of the plugin is built as a standalone executable const DEFAULT_NAME: &'static str = "example"; const PLUGIN_VERSION: &'static str = plugin_version!(); + const PLUGIN_LONG_VERSION: &'static str = plugin_long_version!(); // The first operation called by zenohd on the plugin fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/example-storage-plugin/src/lib.rs index 7757c7f458..2d51e23dfc 100644 --- a/plugins/example-storage-plugin/src/lib.rs +++ b/plugins/example-storage-plugin/src/lib.rs @@ -24,7 +24,7 @@ use zenoh_backend_traits::{ Capability, History, Persistence, Storage, StorageInsertionResult, StoredData, Volume, VolumeInstance, }; -use zenoh_plugin_trait::{plugin_version, Plugin}; +use zenoh_plugin_trait::{plugin_long_version, plugin_version, Plugin}; use zenoh_result::ZResult; zenoh_plugin_trait::declare_plugin!(ExampleBackend); @@ -39,6 +39,7 @@ impl Plugin for ExampleBackend { const DEFAULT_NAME: &'static str = "example_backend"; const PLUGIN_VERSION: &'static str = plugin_version!(); + const PLUGIN_LONG_VERSION: &'static str = plugin_long_version!(); } pub struct ExampleBackend {} diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 9e70f56add..79425ffd62 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -34,7 +34,7 @@ use zenoh::query::{QueryConsolidation, Reply}; use zenoh::runtime::Runtime; use zenoh::selector::TIME_RANGE_KEY; use zenoh::Session; -use zenoh_plugin_trait::{plugin_version, Plugin, PluginControl}; +use zenoh_plugin_trait::{plugin_long_version, plugin_version, Plugin, PluginControl}; use zenoh_result::{bail, zerror, ZResult}; mod config; @@ -219,6 +219,7 @@ impl Plugin for RestPlugin { type Instance = zenoh::plugins::RunningPlugin; const DEFAULT_NAME: &'static str = "rest"; const PLUGIN_VERSION: &'static str = plugin_version!(); + const PLUGIN_LONG_VERSION: &'static str = plugin_long_version!(); fn start(name: &str, runtime: &Self::StartArgs) -> ZResult { // Try to initiate login. diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 3af9a2887e..139d1d258a 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -37,6 +37,7 @@ use zenoh_backend_traits::config::StorageConfig; use zenoh_backend_traits::config::VolumeConfig; use zenoh_backend_traits::VolumeInstance; use zenoh_core::zlock; +use zenoh_plugin_trait::plugin_long_version; use zenoh_plugin_trait::plugin_version; use zenoh_plugin_trait::Plugin; use zenoh_plugin_trait::PluginControl; @@ -57,6 +58,7 @@ impl ZenohPlugin for StoragesPlugin {} impl Plugin for StoragesPlugin { const DEFAULT_NAME: &'static str = "storage_manager"; const PLUGIN_VERSION: &'static str = plugin_version!(); + const PLUGIN_LONG_VERSION: &'static str = plugin_long_version!(); type StartArgs = Runtime; type Instance = zenoh::plugins::RunningPlugin; diff --git a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs index de6f2eed73..ebb4922c9d 100644 --- a/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs +++ b/plugins/zenoh-plugin-storage-manager/src/memory_backend/mod.rs @@ -19,7 +19,7 @@ use zenoh::prelude::r#async::*; use zenoh::time::Timestamp; use zenoh_backend_traits::config::{StorageConfig, VolumeConfig}; use zenoh_backend_traits::*; -use zenoh_plugin_trait::Plugin; +use zenoh_plugin_trait::{plugin_long_version, plugin_version, Plugin}; use zenoh_result::ZResult; use crate::MEMORY_BACKEND_NAME; @@ -33,7 +33,8 @@ impl Plugin for MemoryBackend { type Instance = VolumeInstance; const DEFAULT_NAME: &'static str = MEMORY_BACKEND_NAME; - const PLUGIN_VERSION: &'static str = env!("CARGO_PKG_VERSION"); + const PLUGIN_VERSION: &'static str = plugin_version!(); + const PLUGIN_LONG_VERSION: &'static str = plugin_long_version!(); fn start(_: &str, args: &VolumeConfig) -> ZResult { Ok(Box::new(MemoryBackend { diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index ea6b88f671..48988dfe22 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -62,6 +62,9 @@ impl PluginStatus fn version(&self) -> Option<&str> { self.0.version() } + fn long_version(&self) -> Option<&str> { + self.0.long_version() + } fn path(&self) -> &str { self.0.path() } diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index e4df9ab7ab..3dfd0263fa 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -49,6 +49,7 @@ struct DynamicPluginStarter { _lib: Library, path: PathBuf, plugin_version: &'static str, + plugin_long_version: &'static str, vtable: PluginVTable, } @@ -90,6 +91,7 @@ impl _lib: lib, path, plugin_version: plugin_compatibility_record.plugin_version(), + plugin_long_version: plugin_compatibility_record.plugin_long_version(), vtable, }) } @@ -130,7 +132,9 @@ impl PluginStatus fn version(&self) -> Option<&str> { self.starter.as_ref().map(|v| v.plugin_version) } - + fn long_version(&self) -> Option<&str> { + self.starter.as_ref().map(|v| v.plugin_long_version) + } fn path(&self) -> &str { if let Some(starter) = &self.starter { starter.path() diff --git a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs index 46566c1545..a940695538 100644 --- a/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/static_plugin.rs @@ -45,6 +45,9 @@ where fn version(&self) -> Option<&str> { Some(P::PLUGIN_VERSION) } + fn long_version(&self) -> Option<&str> { + Some(P::PLUGIN_LONG_VERSION) + } fn path(&self) -> &str { "" } diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 7efa4c70fa..438f57fb96 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -63,6 +63,8 @@ pub trait PluginStatus { fn name(&self) -> &str; /// Returns the version of the loaded plugin (usually the version of the plugin's crate) fn version(&self) -> Option<&str>; + /// Returns the long version of the loaded plugin (usually the version of the plugin's crate + git commit hash) + fn long_version(&self) -> Option<&str>; /// Returns the path of the loaded plugin fn path(&self) -> &str; /// Returns the plugin's state (Declared, Loaded, Started) @@ -78,6 +80,7 @@ pub struct PluginStatusRec<'a> { pub name: Cow<'a, str>, #[serde(skip_serializing_if = "Option::is_none")] pub version: Option>, + pub long_version: Option>, pub path: Cow<'a, str>, pub state: PluginState, pub report: PluginReport, @@ -90,6 +93,9 @@ impl PluginStatus for PluginStatusRec<'_> { fn version(&self) -> Option<&str> { self.version.as_deref() } + fn long_version(&self) -> Option<&str> { + self.long_version.as_deref() + } fn path(&self) -> &str { &self.path } @@ -107,6 +113,7 @@ impl<'a> PluginStatusRec<'a> { Self { name: Cow::Borrowed(plugin.name()), version: plugin.version().map(Cow::Borrowed), + long_version: plugin.long_version().map(Cow::Borrowed), path: Cow::Borrowed(plugin.path()), state: plugin.state(), report: plugin.report(), @@ -117,6 +124,7 @@ impl<'a> PluginStatusRec<'a> { PluginStatusRec { name: Cow::Owned(self.name.into_owned()), version: self.version.map(|v| Cow::Owned(v.into_owned())), + long_version: self.long_version.map(|v| Cow::Owned(v.into_owned())), path: Cow::Owned(self.path.into_owned()), state: self.state, report: self.report, @@ -166,12 +174,21 @@ pub trait Plugin: Sized + 'static { const DEFAULT_NAME: &'static str; /// Plugin's version. Used only for information purposes. It's recommended to use [plugin_version!] macro to generate this string. const PLUGIN_VERSION: &'static str; + /// Plugin's long version (with git commit hash). Used only for information purposes. It's recommended to use [plugin_long_version!] macro to generate this string. + const PLUGIN_LONG_VERSION: &'static str; /// Starts your plugin. Use `Ok` to return your plugin's control structure fn start(name: &str, args: &Self::StartArgs) -> ZResult; } #[macro_export] macro_rules! plugin_version { + () => { + env!("CARGO_PKG_VERSION") + }; +} + +#[macro_export] +macro_rules! plugin_long_version { () => { git_version::git_version!(prefix = "v", cargo_prefix = "v") }; diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index d4e51a3ade..6abdbf145d 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -69,6 +69,7 @@ pub struct Compatibility { start_args_version: StructVersion, instance_version: StructVersion, plugin_version: &'static str, + plugin_long_version: &'static str, } impl Compatibility { @@ -82,12 +83,14 @@ impl Compatibility { let start_args_version = StructVersion::new::(); let instance_version = StructVersion::new::(); let plugin_version = PluginType::PLUGIN_VERSION; + let plugin_long_version = PluginType::PLUGIN_LONG_VERSION; Self { rust_version, vtable_version, start_args_version, instance_version, plugin_version, + plugin_long_version, } } pub fn with_empty_plugin_version< @@ -104,11 +107,15 @@ impl Compatibility { start_args_version, instance_version, plugin_version: "", + plugin_long_version: "", } } pub fn plugin_version(&self) -> &'static str { self.plugin_version } + pub fn plugin_long_version(&self) -> &'static str { + self.plugin_long_version + } /// Returns true if rust compiler and structures version are exactly the same and /// plugin version is compatible with the requested version range in the configuration file pub fn are_compatible(&self, other: &Self) -> bool { From 428bae77dd5464c0dd04865478459303cda1267b Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 15 Jan 2024 18:00:23 +0100 Subject: [PATCH 089/106] default impls for RunningPluginTrait, doc comments --- plugins/example-plugin/src/lib.rs | 10 ------- plugins/zenoh-plugin-rest/src/lib.rs | 9 ------ zenoh/src/plugins/sealed.rs | 41 ++++++++++++++++++++++------ 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/plugins/example-plugin/src/lib.rs b/plugins/example-plugin/src/lib.rs index c37b45399c..ee07361ff9 100644 --- a/plugins/example-plugin/src/lib.rs +++ b/plugins/example-plugin/src/lib.rs @@ -129,16 +129,6 @@ impl RunningPluginTrait for RunningPlugin { } bail!("unknown option {} for {}", path, guard.name) } - - // Function called on any query on admin space that matches this plugin's sub-part of the admin space. - // Thus the plugin can reply its contribution to the global admin space of this zenohd. - fn adminspace_getter<'a>( - &'a self, - _selector: &'a Selector<'a>, - _plugin_status_key: &str, - ) -> ZResult> { - Ok(Vec::new()) - } } // If the plugin is dropped, set the flag to false to end the loop diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 79425ffd62..56b619f0a8 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -249,15 +249,6 @@ struct RunningPlugin(Config); impl PluginControl for RunningPlugin {} impl RunningPluginTrait for RunningPlugin { - fn config_checker( - &self, - _: &str, - _: &serde_json::Map, - _: &serde_json::Map, - ) -> ZResult>> { - bail!("zenoh-plugin-rest doesn't accept any runtime configuration changes") - } - fn adminspace_getter<'a>( &'a self, selector: &'a Selector<'a>, diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 8adbde4162..f417411c38 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -82,16 +82,41 @@ pub trait RunningPluginTrait: Send + Sync + PluginControl { /// * `Ok(Some(value))` indicates that the plugin would rather the new configuration be `value`. fn config_checker( &self, - path: &str, - current: &serde_json::Map, - new: &serde_json::Map, - ) -> ZResult>>; - /// Used to request your plugin's status for the administration space. + _path: &str, + _current: &serde_json::Map, + _new: &serde_json::Map, + ) -> ZResult>> { + bail!("Runtime configuration change not supported"); + } + /// Used to request plugin's status for the administration space. + /// Function called on any query on admin space that matches this plugin's sub-part of the admin space. + /// Thus the plugin can reply its contribution to the global admin space of this zenohd. + /// Parameters: + /// * `selector`: the full selector of the query (usually only key_expr part is used). This selector is + /// exactly the same as it was requested by user, for example "@/router/ROUTER_ID/plugins/PLUGIN_NAME/some/plugin/info" or "@/router/*/plugins/*/foo/bar". + /// But the plugin's [adminspace_getter] is called only if the selector matches the [plugin_status_key] + /// * `plugin_status_key`: the actual path to plugin's status in the admin space. For example "@/router/ROUTER_ID/plugins/PLUGIN_NAME" + /// Returns value: + /// * `Ok(Vec)`: the list of responses to the query. For example if plugins can return information on subleys "foo", "bar", "foo/buzz" and "bar/buzz" + /// and it's requested with the query "@/router/ROUTER_ID/plugins/PLUGIN_NAME/*", it should return only information on "foo" and "bar" subkeys, but not on "foo/buzz" and "bar/buzz" + /// as they doesn't match the query. + /// * `Err(ZError)`: Problem occured when processing the query. + /// + /// If plugin implements subplugins (as the storage plugin), then it should also reply with information about its subplugins with the same rules. + /// + /// TODO: + /// * add example + /// * rework the admin space: rework "with_extented_string" function, provide it as utility for plugins + /// * reorder paramaters: plugin_status_key should be first as it describes the root of pluginb's admin space + /// * Instead of ZResult return just Vec. Check, do we really need ZResult? If yes, make it separate for each status record. + /// fn adminspace_getter<'a>( &'a self, - selector: &'a Selector<'a>, - plugin_status_key: &str, - ) -> ZResult>; + _selector: &'a Selector<'a>, + _plugin_status_key: &str, + ) -> ZResult> { + Ok(Vec::new()) + } } /// The zenoh plugins manager. It handles the full lifetime of plugins, from loading to destruction. From 0d3393e5b3999b8a6168e18cc2119d37c6958e84 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 15 Jan 2024 18:34:57 +0100 Subject: [PATCH 090/106] todos added --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 1 + zenoh/src/net/runtime/adminspace.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 139d1d258a..6732bbe4f6 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -289,6 +289,7 @@ impl RunningPluginTrait for StorageRuntime { ) -> ZResult> { let mut responses = Vec::new(); let mut key = String::from(plugin_status_key); + // TODO: to be removed when "__version__" is implemented in admin space with_extended_string(&mut key, &["/version"], |key| { if keyexpr::new(key.as_str()) .unwrap() diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index a2b9d714ce..d8b25c2c6d 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -683,6 +683,7 @@ fn plugins_status(context: &AdminContext, query: Query) { for plugin in guard.started_plugins() { with_extended_string(&mut root_key, &[plugin.name()], |plugin_key| { + // TODO: reqponse to "__version__" also, this need noot to be implemented by each plugin with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { if let Ok(key_expr) = KeyExpr::try_from(plugin_path_key.clone()) { if query.key_expr().intersects(&key_expr) { From 18e6212a3d930ca1f9c6ad9fa78b1b23089a8ecf Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 16 Jan 2024 16:29:12 +0100 Subject: [PATCH 091/106] cargo fmt --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 2 +- zenoh/src/plugins/sealed.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 6732bbe4f6..d718258df7 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -289,7 +289,7 @@ impl RunningPluginTrait for StorageRuntime { ) -> ZResult> { let mut responses = Vec::new(); let mut key = String::from(plugin_status_key); - // TODO: to be removed when "__version__" is implemented in admin space + // TODO: to be removed when "__version__" is implemented in admoin space with_extended_string(&mut key, &["/version"], |key| { if keyexpr::new(key.as_str()) .unwrap() diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index f417411c38..9ff0311e7d 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -93,23 +93,23 @@ pub trait RunningPluginTrait: Send + Sync + PluginControl { /// Thus the plugin can reply its contribution to the global admin space of this zenohd. /// Parameters: /// * `selector`: the full selector of the query (usually only key_expr part is used). This selector is - /// exactly the same as it was requested by user, for example "@/router/ROUTER_ID/plugins/PLUGIN_NAME/some/plugin/info" or "@/router/*/plugins/*/foo/bar". + /// exactly the same as it was requested by user, for example "@/router/ROUTER_ID/plugins/PLUGIN_NAME/some/plugin/info" or "@/router/*/plugins/*/foo/bar". /// But the plugin's [adminspace_getter] is called only if the selector matches the [plugin_status_key] /// * `plugin_status_key`: the actual path to plugin's status in the admin space. For example "@/router/ROUTER_ID/plugins/PLUGIN_NAME" /// Returns value: - /// * `Ok(Vec)`: the list of responses to the query. For example if plugins can return information on subleys "foo", "bar", "foo/buzz" and "bar/buzz" + /// * `Ok(Vec)`: the list of responses to the query. For example if plugins can return information on subleys "foo", "bar", "foo/buzz" and "bar/buzz" /// and it's requested with the query "@/router/ROUTER_ID/plugins/PLUGIN_NAME/*", it should return only information on "foo" and "bar" subkeys, but not on "foo/buzz" and "bar/buzz" /// as they doesn't match the query. - /// * `Err(ZError)`: Problem occured when processing the query. - /// + /// * `Err(ZError)`: Problem occured when processing the query. + /// /// If plugin implements subplugins (as the storage plugin), then it should also reply with information about its subplugins with the same rules. - /// - /// TODO: + /// + /// TODO: /// * add example /// * rework the admin space: rework "with_extented_string" function, provide it as utility for plugins /// * reorder paramaters: plugin_status_key should be first as it describes the root of pluginb's admin space /// * Instead of ZResult return just Vec. Check, do we really need ZResult? If yes, make it separate for each status record. - /// + /// fn adminspace_getter<'a>( &'a self, _selector: &'a Selector<'a>, From 8ccf6da7f55979d6d19737376a753f0668d10bbb Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 17 Jan 2024 17:17:43 +0100 Subject: [PATCH 092/106] diagnostic improved, test config partially made, path renamings --- .../{example-storage-plugin => zenoh-backend-example}/Cargo.toml | 0 .../config.json5 | 0 .../{example-storage-plugin => zenoh-backend-example}/src/lib.rs | 0 plugins/{example-plugin => zenoh-plugin-example}/Cargo.toml | 0 plugins/{example-plugin => zenoh-plugin-example}/README.md | 0 plugins/{example-plugin => zenoh-plugin-example}/src/lib.rs | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{example-storage-plugin => zenoh-backend-example}/Cargo.toml (100%) rename plugins/{example-storage-plugin => zenoh-backend-example}/config.json5 (100%) rename plugins/{example-storage-plugin => zenoh-backend-example}/src/lib.rs (100%) rename plugins/{example-plugin => zenoh-plugin-example}/Cargo.toml (100%) rename plugins/{example-plugin => zenoh-plugin-example}/README.md (100%) rename plugins/{example-plugin => zenoh-plugin-example}/src/lib.rs (100%) diff --git a/plugins/example-storage-plugin/Cargo.toml b/plugins/zenoh-backend-example/Cargo.toml similarity index 100% rename from plugins/example-storage-plugin/Cargo.toml rename to plugins/zenoh-backend-example/Cargo.toml diff --git a/plugins/example-storage-plugin/config.json5 b/plugins/zenoh-backend-example/config.json5 similarity index 100% rename from plugins/example-storage-plugin/config.json5 rename to plugins/zenoh-backend-example/config.json5 diff --git a/plugins/example-storage-plugin/src/lib.rs b/plugins/zenoh-backend-example/src/lib.rs similarity index 100% rename from plugins/example-storage-plugin/src/lib.rs rename to plugins/zenoh-backend-example/src/lib.rs diff --git a/plugins/example-plugin/Cargo.toml b/plugins/zenoh-plugin-example/Cargo.toml similarity index 100% rename from plugins/example-plugin/Cargo.toml rename to plugins/zenoh-plugin-example/Cargo.toml diff --git a/plugins/example-plugin/README.md b/plugins/zenoh-plugin-example/README.md similarity index 100% rename from plugins/example-plugin/README.md rename to plugins/zenoh-plugin-example/README.md diff --git a/plugins/example-plugin/src/lib.rs b/plugins/zenoh-plugin-example/src/lib.rs similarity index 100% rename from plugins/example-plugin/src/lib.rs rename to plugins/zenoh-plugin-example/src/lib.rs From 328371e2adebaba8ce68091391a3133fa0a2a6af Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 17 Jan 2024 17:19:10 +0100 Subject: [PATCH 093/106] diagnostic improved, test config partially made, path renamings --- Cargo.lock | 42 ++--- Cargo.toml | 4 +- plugin_test_config.json5 | 62 +++++++- plugins/zenoh-backend-example/Cargo.toml | 2 +- plugins/zenoh-backend-traits/src/config.rs | 3 + .../src/backends_mgt.rs | 2 +- .../zenoh-plugin-storage-manager/src/lib.rs | 38 ++--- .../src/replica/storage.rs | 26 ++-- .../src/storages_mgt.rs | 2 +- .../src/manager/dynamic_plugin.rs | 29 ++-- plugins/zenoh-plugin-trait/src/vtable.rs | 146 +++++++++++++----- 11 files changed, 240 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e73f7976e..a03e85fd79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4607,6 +4607,27 @@ dependencies = [ "zenoh-util", ] +[[package]] +name = "zenoh-backend-example" +version = "0.11.0-dev" +dependencies = [ + "async-std", + "async-trait", + "clap", + "const_format", + "env_logger", + "futures", + "git-version", + "log", + "serde_json", + "zenoh", + "zenoh-core", + "zenoh-plugin-trait", + "zenoh-result", + "zenoh-util", + "zenoh_backend_traits", +] + [[package]] name = "zenoh-buffers" version = "0.11.0-dev" @@ -4983,27 +5004,6 @@ dependencies = [ "zenoh-util", ] -[[package]] -name = "zenoh-plugin-storage-example" -version = "0.11.0-dev" -dependencies = [ - "async-std", - "async-trait", - "clap", - "const_format", - "env_logger", - "futures", - "git-version", - "log", - "serde_json", - "zenoh", - "zenoh-core", - "zenoh-plugin-trait", - "zenoh-result", - "zenoh-util", - "zenoh_backend_traits", -] - [[package]] name = "zenoh-plugin-storage-manager" version = "0.11.0-dev" diff --git a/Cargo.toml b/Cargo.toml index f6249de921..918c432073 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,8 +39,8 @@ members = [ "io/zenoh-links/zenoh-link-ws/", "io/zenoh-links/zenoh-link-unixpipe/", "io/zenoh-transport", - "plugins/example-plugin", - "plugins/example-storage-plugin", + "plugins/zenoh-backend-example", + "plugins/zenoh-plugin-example", "plugins/zenoh-backend-traits", "plugins/zenoh-plugin-rest", "plugins/zenoh-plugin-storage-manager", diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 index e5575c905d..9461b9acce 100644 --- a/plugin_test_config.json5 +++ b/plugin_test_config.json5 @@ -1,13 +1,67 @@ +// Config for testing all available plugins +// +// To run it do these steps: +// +// - Clone these repositories: +// ``` +// git clone https://github.com/eclipse-zenoh/zenoh.git +// git clone https://github.com/eclipse-zenoh/zenoh-backend-influxdb.git +// git clone https://github.com/eclipse-zenoh/zenoh-backend-rocksdb.git +// git clone https://github.com/eclipse-zenoh/zenoh-backend-filesystem.git +// git clone https://github.com/eclipse-zenoh/zenoh-plugin-webserver.git +// git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git +// git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git +// git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git +// git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git +// ``` +// +// - Init submodules for zenoh-plugin-ros1 +// ``` +// cd zenoh-plugin-ros1 +// git submodule init +// git submodule update +// ``` +// +// - Build projects +// ``` +// cd zenoh && cargo build && cd .. +// cd zenoh-backend-influxdb && cargo build && cd .. +// ... +// ``` +// +// - Run the zenohd server with this config file. +// Explicit setting RUST_LOG=info is important: without it the logs with default le are printed by zenohd itsellf, but not by plugins. +// ``` +// cd zenoh +// RUST_LOG=info cargo run -- --config plugin_test_config.json5 +// ``` +// +// { "plugins": { + // demonstrate "nof found" error + "not_found": { + }, + // example plugin, see "plugins/zenog-plugin-example" + "example": { + }, + // rest plugin, see "plugins/zenoh-plugin-rest" "rest": { "http_port": 8080, }, + // storage mangaer plugin, see "plugins/zenoh-plugin-storage-manager" + // supports different backends implemented as plugins also "storage_manager": { + backend_search_dirs: [ + "../zenoh-backend-influxdb/target/debug", + ], "volumes": { + // example backend, see "plugins/zenoh-backend-example" "example": { - "__path__": ["target/debug/libzenoh_backend_example.so","target/debug/libzenoh_backend_example.dylib"], - } + }, + // influxdb backend from "../zenoh-backend-influxdb" + "influxdb": { + }, }, "storages": { "memory": { @@ -20,10 +74,6 @@ }, } }, - "not_found": { - }, - "example": { - }, "dds": { "__path__": ["../zenoh-plugin-dds/target/debug/libzenoh_plugin_dds.so","../zenoh-plugin-dds/target/debug/libzenoh_plugin_dds.dylib"], } diff --git a/plugins/zenoh-backend-example/Cargo.toml b/plugins/zenoh-backend-example/Cargo.toml index 0e532691c8..eac0e0d803 100644 --- a/plugins/zenoh-backend-example/Cargo.toml +++ b/plugins/zenoh-backend-example/Cargo.toml @@ -13,7 +13,7 @@ # [package] rust-version = { workspace = true } -name = "zenoh-plugin-storage-example" +name = "zenoh-backend-example" version = { workspace = true } authors = { workspace = true } edition = { workspace = true } diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index e3ccd2f524..f2f05a8eef 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -324,6 +324,9 @@ impl VolumeConfig { } } impl StorageConfig { + pub fn name(&self) -> &str { + &self.name + } pub fn to_json_value(&self) -> Value { let mut result = serde_json::Map::new(); result.insert("key_expr".into(), Value::String(self.key_expr.to_string())); diff --git a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs index 85c4ebf48d..aa7260e868 100644 --- a/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs +++ b/plugins/zenoh-plugin-storage-manager/src/backends_mgt.rs @@ -35,7 +35,7 @@ pub(crate) async fn create_and_start_storage( out_interceptor: Option Sample + Send + Sync>>, zenoh: Arc, ) -> ZResult> { - log::trace!("Create storage {}", &admin_key); + log::trace!("Create storage '{}'", &admin_key); let capability = backend.get_capability(); let storage = backend.create_storage(config.clone()).await?; let store_intercept = StoreIntercept { diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index d718258df7..117779dba8 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -124,28 +124,28 @@ impl StorageRuntimeInner { plugins_manager, }; new_self - .spawn_volume(VolumeConfig { + .spawn_volume(&VolumeConfig { name: MEMORY_BACKEND_NAME.into(), backend: None, paths: None, required: false, rest: Default::default(), }) - .map_or_else(|e| log::error!("Cannot spawn memory volume: {}", e), |_| ()); - for volume in volumes { + .map_or_else(|e| log::error!("Cannot spawn static volume '{}': {}", MEMORY_BACKEND_NAME, e), |_| ()); + for volume in &volumes { new_self .spawn_volume(volume) - .map_or_else(|e| log::error!("Cannot spawn volume: {}", e), |_| ()); + .map_or_else(|e| log::error!("Cannot spawn volume '{}': {}", volume.name(), e), |_| ()); } - for storage in storages { + for storage in &storages { new_self .spawn_storage(storage) - .map_or_else(|e| log::error!("Cannot spawn storage: {}", e), |_| ()); + .map_or_else(|e| log::error!("Cannot spawn storage '{}': {}", storage.name(), e), |_| ()); } Ok(new_self) } fn update>(&mut self, diffs: I) -> ZResult<()> { - for diff in diffs { + for ref diff in diffs { match diff { ConfigDiff::DeleteVolume(volume) => self.kill_volume(&volume.name)?, ConfigDiff::AddVolume(volume) => { @@ -159,7 +159,7 @@ impl StorageRuntimeInner { } fn kill_volume>(&mut self, name: T) -> ZResult<()> { let name = name.as_ref(); - log::info!("Killing volume {}", name); + log::info!("Killing volume '{}'", name); if let Some(storages) = self.storages.remove(name) { async_std::task::block_on(futures::future::join_all( storages @@ -169,15 +169,15 @@ impl StorageRuntimeInner { } self.plugins_manager .started_plugin_mut(name) - .ok_or(format!("Cannot find volume {} to stop it", name))? + .ok_or(format!("Cannot find volume '{}' to stop it", name))? .stop(); Ok(()) } - fn spawn_volume(&mut self, config: VolumeConfig) -> ZResult<()> { + fn spawn_volume(&mut self, config: &VolumeConfig) -> ZResult<()> { let volume_id = config.name(); let backend_name = config.backend(); log::info!( - "Spawning volume {} with backend {}", + "Spawning volume '{}' with backend '{}'", volume_id, backend_name ); @@ -191,16 +191,16 @@ impl StorageRuntimeInner { .declare_dynamic_plugin_by_name(volume_id, backend_name)? }; let loaded = declared.load()?; - loaded.start(&config)?; + loaded.start(config)?; Ok(()) } - fn kill_storage(&mut self, config: StorageConfig) { + fn kill_storage(&mut self, config: &StorageConfig) { let volume = &config.volume_id; - log::info!("Killing storage {} from volume {}", config.name, volume); + log::info!("Killing storage '{}' from volume '{}'", config.name, volume); if let Some(storages) = self.storages.get_mut(volume) { if let Some(storage) = storages.get_mut(&config.name) { log::debug!( - "Closing storage {} from volume {}", + "Closing storage '{}' from volume '{}'", config.name, config.volume_id ); @@ -209,19 +209,19 @@ impl StorageRuntimeInner { } } } - fn spawn_storage(&mut self, storage: StorageConfig) -> ZResult<()> { + fn spawn_storage(&mut self, storage: &StorageConfig) -> ZResult<()> { let admin_key = self.status_key() + "/storages/" + &storage.name; let volume_id = storage.volume_id.clone(); let backend = self .plugins_manager .started_plugin(&volume_id) .ok_or(format!( - "Cannot find volume {} to spawn storage {}", + "Cannot find volume '{}' to spawn storage '{}'", volume_id, storage.name ))?; let storage_name = storage.name.clone(); log::info!( - "Spawning storage {} from volume {} with backend {}", + "Spawning storage '{}' from volume '{}' with backend '{}'", storage_name, volume_id, backend.name() @@ -230,7 +230,7 @@ impl StorageRuntimeInner { let out_interceptor = backend.instance().outgoing_data_interceptor(); let stopper = async_std::task::block_on(create_and_start_storage( admin_key, - storage, + storage.clone(), backend.instance(), in_interceptor, out_interceptor, diff --git a/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs b/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs index 16f5fd4a36..84f592d899 100644 --- a/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs +++ b/plugins/zenoh-plugin-storage-manager/src/replica/storage.rs @@ -146,7 +146,7 @@ impl StorageService { let storage_sub = match self.session.declare_subscriber(&self.key_expr).res().await { Ok(storage_sub) => storage_sub, Err(e) => { - log::error!("Error starting storage {}: {}", self.name, e); + log::error!("Error starting storage '{}': {}", self.name, e); return; } }; @@ -161,7 +161,7 @@ impl StorageService { { Ok(storage_queryable) => storage_queryable, Err(e) => { - log::error!("Error starting storage {}: {}", self.name, e); + log::error!("Error starting storage '{}': {}", self.name, e); return; } }; @@ -205,7 +205,7 @@ impl StorageService { message = rx.recv_async() => { match message { Ok(StorageMessage::Stop) => { - log::trace!("Dropping storage {}", self.name); + log::trace!("Dropping storage '{}'", self.name); return }, Ok(StorageMessage::GetStatus(tx)) => { @@ -243,7 +243,7 @@ impl StorageService { message = rx.recv_async() => { match message { Ok(StorageMessage::Stop) => { - log::trace!("Dropping storage {}", self.name); + log::trace!("Dropping storage '{}'", self.name); return }, Ok(StorageMessage::GetStatus(tx)) => { @@ -458,7 +458,7 @@ impl StorageService { } Err(e) => { log::warn!( - "Storage {} raised an error fetching a query on key {} : {}", + "Storage '{}' raised an error fetching a query on key {} : {}", self.name, key_expr, e @@ -527,14 +527,14 @@ impl StorageService { }; if let Err(e) = q.reply(Ok(sample)).res().await { log::warn!( - "Storage {} raised an error replying a query: {}", + "Storage '{}' raised an error replying a query: {}", self.name, e ) } } } - Err(e) => log::warn!("Storage {} raised an error on query: {}", self.name, e), + Err(e) => log::warn!("Storage'{}' raised an error on query: {}", self.name, e), }; } drop(storage); @@ -561,7 +561,7 @@ impl StorageService { }; if let Err(e) = q.reply(Ok(sample)).res().await { log::warn!( - "Storage {} raised an error replying a query: {}", + "Storage '{}' raised an error replying a query: {}", self.name, e ) @@ -570,11 +570,11 @@ impl StorageService { } Err(e) => { let err_message = - format!("Storage {} raised an error on query: {}", self.name, e); + format!("Storage '{}' raised an error on query: {}", self.name, e); log::warn!("{}", err_message); if let Err(e) = q.reply(Err(err_message.into())).res().await { log::warn!( - "Storage {} raised an error replying a query: {}", + "Storage '{}' raised an error replying a query: {}", self.name, e ) @@ -602,7 +602,7 @@ impl StorageService { } } Err(e) => log::warn!( - "Storage {} raised an error while retrieving keys: {}", + "Storage '{}' raised an error while retrieving keys: {}", self.name, e ), @@ -659,7 +659,7 @@ impl StorageService { { Ok(replies) => replies, Err(e) => { - log::error!("Error aligning storage {}: {}", self.name, e); + log::error!("Error aligning storage '{}': {}", self.name, e); return; } }; @@ -669,7 +669,7 @@ impl StorageService { self.process_sample(sample).await; } Err(e) => log::warn!( - "Storage {} received an error to align query: {}", + "Storage '{}' received an error to align query: {}", self.name, e ), diff --git a/plugins/zenoh-plugin-storage-manager/src/storages_mgt.rs b/plugins/zenoh-plugin-storage-manager/src/storages_mgt.rs index 7bf1714206..6de5e2f2ca 100644 --- a/plugins/zenoh-plugin-storage-manager/src/storages_mgt.rs +++ b/plugins/zenoh-plugin-storage-manager/src/storages_mgt.rs @@ -35,7 +35,7 @@ pub(crate) async fn start_storage( let storage_name = parts[7]; let name = format!("{uuid}/{storage_name}"); - log::trace!("Start storage {} on {}", name, config.key_expr); + log::trace!("Start storage '{}' on keyexpr '{}'", name, config.key_expr); let (tx, rx) = flume::bounded(1); diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index 3dfd0263fa..5377e1547e 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -11,7 +11,7 @@ // ZettaScale Zenoh Team, // use crate::*; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use libloading::Library; use zenoh_result::{bail, ZResult}; @@ -48,16 +48,14 @@ impl DynamicPluginSource { struct DynamicPluginStarter { _lib: Library, path: PathBuf, - plugin_version: &'static str, - plugin_long_version: &'static str, vtable: PluginVTable, } impl DynamicPluginStarter { - fn new(lib: Library, path: PathBuf) -> ZResult { - log::debug!("Loading plugin {}", &path.to_str().unwrap(),); + fn get_vtable(lib: &Library, path: &Path) -> ZResult> { + log::debug!("Loading plugin {}", path.to_str().unwrap(),); let get_plugin_loader_version = unsafe { lib.get:: PluginLoaderVersion>(b"get_plugin_loader_version")? }; let plugin_loader_version = get_plugin_loader_version(); @@ -70,28 +68,31 @@ impl ); } let get_compatibility = unsafe { lib.get:: Compatibility>(b"get_compatibility")? }; - let plugin_compatibility_record = get_compatibility(); - let host_compatibility_record = + let mut plugin_compatibility_record = get_compatibility(); + let mut host_compatibility_record = Compatibility::with_empty_plugin_version::(); log::debug!( "Plugin compativilty record: {:?}", &plugin_compatibility_record ); - if !plugin_compatibility_record.are_compatible(&host_compatibility_record) { + if !plugin_compatibility_record.compare(&mut host_compatibility_record) { bail!( - "Plugin compatibility mismatch:\n\nHost:\n{}\nPlugin:\n{}\n", + "Plugin compatibility mismatch:\nHost:\n{}Plugin:\n{}", host_compatibility_record, plugin_compatibility_record ); } let load_plugin = unsafe { lib.get:: PluginVTable>(b"load_plugin")? }; - let vtable = load_plugin(); + + Ok(load_plugin()) + } + fn new(lib: Library, path: PathBuf) -> ZResult { + let vtable = Self::get_vtable(&lib, &path) + .map_err(|e| format!("Error loading {}: {}", path.to_str().unwrap(), e))?; Ok(Self { _lib: lib, path, - plugin_version: plugin_compatibility_record.plugin_version(), - plugin_long_version: plugin_compatibility_record.plugin_long_version(), vtable, }) } @@ -130,10 +131,10 @@ impl PluginStatus self.name.as_str() } fn version(&self) -> Option<&str> { - self.starter.as_ref().map(|v| v.plugin_version) + self.starter.as_ref().map(|v| v.vtable.plugin_version) } fn long_version(&self) -> Option<&str> { - self.starter.as_ref().map(|v| v.plugin_long_version) + self.starter.as_ref().map(|v| v.vtable.plugin_long_version) } fn path(&self) -> &str { if let Some(starter) = &self.starter { diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 6abdbf145d..7541c4a41a 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -22,11 +22,13 @@ type StartFn = fn(&str, &StartArgs) -> ZResult; #[repr(C)] pub struct PluginVTable { + pub plugin_version: &'static str, + pub plugin_long_version: &'static str, pub start: StartFn, } impl PluginStructVersion for PluginVTable { fn struct_version() -> u64 { - 1 + 2 } fn struct_features() -> &'static str { FEATURES @@ -64,12 +66,12 @@ impl Display for StructVersion { #[repr(C)] #[derive(Debug, PartialEq, Eq, Clone)] pub struct Compatibility { - rust_version: RustVersion, - vtable_version: StructVersion, - start_args_version: StructVersion, - instance_version: StructVersion, - plugin_version: &'static str, - plugin_long_version: &'static str, + rust_version: Option, + vtable_version: Option, + start_args_version: Option, + instance_version: Option, + plugin_version: Option<&'static str>, + plugin_long_version: Option<&'static str>, } impl Compatibility { @@ -78,12 +80,14 @@ impl Compatibility { InstanceType: PluginInstance, PluginType: Plugin, >() -> Self { - let rust_version = RustVersion::new(); - let vtable_version = StructVersion::new::>(); - let start_args_version = StructVersion::new::(); - let instance_version = StructVersion::new::(); - let plugin_version = PluginType::PLUGIN_VERSION; - let plugin_long_version = PluginType::PLUGIN_LONG_VERSION; + let rust_version = Some(RustVersion::new()); + let vtable_version = Some(StructVersion::new::< + PluginVTable, + >()); + let start_args_version = Some(StructVersion::new::()); + let instance_version = Some(StructVersion::new::()); + let plugin_version = Some(PluginType::PLUGIN_VERSION); + let plugin_long_version = Some(PluginType::PLUGIN_LONG_VERSION); Self { rust_version, vtable_version, @@ -97,47 +101,111 @@ impl Compatibility { StartArgsType: PluginStartArgs, InstanceType: PluginInstance, >() -> Self { - let rust_version = RustVersion::new(); - let vtable_version = StructVersion::new::>(); - let start_args_version = StructVersion::new::(); - let instance_version = StructVersion::new::(); + let rust_version = Some(RustVersion::new()); + let vtable_version = Some(StructVersion::new::< + PluginVTable, + >()); + let start_args_version = Some(StructVersion::new::()); + let instance_version = Some(StructVersion::new::()); Self { rust_version, vtable_version, start_args_version, instance_version, - plugin_version: "", - plugin_long_version: "", + plugin_version: None, + plugin_long_version: None, } } - pub fn plugin_version(&self) -> &'static str { + pub fn plugin_version(&self) -> Option<&'static str> { self.plugin_version } - pub fn plugin_long_version(&self) -> &'static str { + pub fn plugin_long_version(&self) -> Option<&'static str> { self.plugin_long_version } - /// Returns true if rust compiler and structures version are exactly the same and - /// plugin version is compatible with the requested version range in the configuration file - pub fn are_compatible(&self, other: &Self) -> bool { - RustVersion::are_compatible(&self.rust_version, &other.rust_version) - && self.vtable_version == other.vtable_version - && self.start_args_version == other.start_args_version - && self.instance_version == other.instance_version - // TODO: check plugin version may be added later + /// Compares fields if both are Some, otherwise skips the comparison. + /// Returns true if all the comparisons returned true, otherwise false. + /// If comparison passed or skipped, the corresponding field in both structs is set to None. + /// If comparison failed, the corresponding field in both structs is kept as is. + /// This allows not only to check compatibility, but also point to exact reasons of incompatibility. + pub fn compare(&mut self, other: &mut Self) -> bool { + let mut result = true; + Self::compare_field_fn( + &mut result, + &mut self.rust_version, + &mut other.rust_version, + RustVersion::are_compatible, + ); + Self::compare_field( + &mut result, + &mut self.vtable_version, + &mut other.vtable_version, + ); + Self::compare_field( + &mut result, + &mut self.start_args_version, + &mut other.start_args_version, + ); + Self::compare_field( + &mut result, + &mut self.instance_version, + &mut other.instance_version, + ); + // TODO: here we can later implement check for plugin version range compatibility + Self::compare_field( + &mut result, + &mut self.plugin_version, + &mut other.plugin_version, + ); + Self::compare_field( + &mut result, + &mut self.plugin_long_version, + &mut other.plugin_long_version, + ); + result + } + + // Utility function for compare single field + fn compare_field_fn bool>( + result: &mut bool, + a: &mut Option, + b: &mut Option, + compare: F, + ) { + let compatible = if let (Some(a), Some(b)) = (&a, &b) { + compare(a, b) + } else { + true + }; + if compatible { + *a = None; + *b = None; + } else { + *result = false; + } + } + fn compare_field(result: &mut bool, a: &mut Option, b: &mut Option) { + Self::compare_field_fn(result, a, b, |a, b| a == b); } } impl Display for Compatibility { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}\nVTable:{}StartArgs:{}Instance:{}Plugin:{}", - self.rust_version, - self.vtable_version, - self.start_args_version, - self.instance_version, - self.plugin_version - ) + if let Some(rust_version) = &self.rust_version { + writeln!(f, "Rust version:\n{}", rust_version)?; + } + if let Some(vtable_version) = &self.vtable_version { + writeln!(f, "VTable version:\n{}", vtable_version)?; + } + if let Some(start_args_version) = &self.start_args_version { + writeln!(f, "StartArgs version:\n{}", start_args_version)?; + } + if let Some(instance_version) = &self.instance_version { + writeln!(f, "Instance version:\n{}", instance_version)?; + } + if let Some(plugin_version) = &self.plugin_version { + writeln!(f, "Plugin version: {}", plugin_version)?; + } + Ok(()) } } @@ -201,6 +269,8 @@ impl Default for RustVersion { impl PluginVTable { pub fn new>() -> Self { Self { + plugin_version: ConcretePlugin::PLUGIN_VERSION, + plugin_long_version: ConcretePlugin::PLUGIN_LONG_VERSION, start: ConcretePlugin::start, } } From 4e1b13a9672bd32301e3125d26b38399403755db Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 17 Jan 2024 17:42:38 +0100 Subject: [PATCH 094/106] incorrect warn replaced to debug --- plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs index 5377e1547e..1153f8a6ed 100644 --- a/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs +++ b/plugins/zenoh-plugin-trait/src/manager/dynamic_plugin.rs @@ -36,7 +36,7 @@ impl DynamicPluginSource { for path in paths { match unsafe { LibLoader::load_file(path) } { Ok((l, p)) => return Ok((l, p)), - Err(e) => log::warn!("Plugin {} load fail: {}", path, e), + Err(e) => log::debug!("Attempt to load {} failed: {}", path, e), } } bail!("Plugin not found in {:?}", &paths) From 912f5ae11d3d69ca86d6f1b831bf2ca766bd58c3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 17 Jan 2024 18:19:57 +0100 Subject: [PATCH 095/106] no_mangle into plugin's code --- Cargo.lock | 1258 +++++++++-------- plugin_test_config.json5 | 14 +- plugins/zenoh-backend-example/src/lib.rs | 1 + plugins/zenoh-plugin-example/src/lib.rs | 1 + plugins/zenoh-plugin-rest/src/lib.rs | 2 + .../zenoh-plugin-storage-manager/src/lib.rs | 2 + plugins/zenoh-plugin-trait/src/vtable.rs | 6 +- 7 files changed, 698 insertions(+), 586 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a03e85fd79..c9c7ba2fea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,27 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "CoreFoundation-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b" -dependencies = [ - "libc", - "mach", -] - -[[package]] -name = "IOKit-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a" -dependencies = [ - "CoreFoundation-sys", - "libc", - "mach", -] - [[package]] name = "addr2line" version = "0.21.0" @@ -115,22 +94,23 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.10", + "getrandom 0.2.12", "once_cell", "serde", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -164,9 +144,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "628a8f9bd1e24b4e0db2b4bc2d000b001e7dd032d54afa60a68836aeec5aa54a" dependencies = [ "anstyle", "anstyle-parse", @@ -178,26 +158,26 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -212,9 +192,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "array-init" @@ -255,56 +235,70 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-channel" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +dependencies = [ + "concurrent-queue", + "event-listener 4.0.3", + "event-listener-strategy", + "futures-core", + "pin-project-lite 0.2.13", +] + [[package]] name = "async-dup" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7427a12b8dc09291528cfb1da2447059adb4a257388c2acd6497a79d55cf6f7c" +checksum = "7c2886ab563af5038f79ec016dd7b87947ed138b794e8dd64992962c9cca0411" dependencies = [ + "async-lock 3.3.0", "futures-io", - "simple-mutex", ] [[package]] name = "async-executor" -version = "1.5.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" dependencies = [ - "async-lock", + "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand", - "futures-lite", + "fastrand 2.0.1", + "futures-lite 2.2.0", "slab", ] [[package]] name = "async-global-executor" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel", + "async-channel 2.1.1", "async-executor", - "async-io", - "async-lock", + "async-io 2.3.0", + "async-lock 3.3.0", "blocking", - "futures-lite", + "futures-lite 2.2.0", "once_cell", "tokio", ] [[package]] name = "async-h1" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8101020758a4fc3a7c326cb42aa99e9fa77cbfb76987c128ad956406fe1f70a7" +checksum = "5d1d1dae8cb2c4258a79d6ed088b7fb9b4763bf4e9b22d040779761e046a2971" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-dup", - "async-std", - "futures-core", + "async-global-executor", + "async-io 1.13.0", + "futures-lite 1.13.0", "http-types", "httparse", "log", @@ -317,20 +311,39 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if 1.0.0", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", - "polling", - "rustix 0.37.25", + "polling 2.8.0", + "rustix 0.37.27", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744" +dependencies = [ + "async-lock 3.3.0", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite 2.2.0", + "parking", + "polling 3.3.2", + "rustix 0.38.30", + "slab", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -340,29 +353,39 @@ dependencies = [ "event-listener 2.5.3", ] +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy", + "pin-project-lite 0.2.13", +] + [[package]] name = "async-process" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ - "async-io", - "async-lock", - "autocfg", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", "blocking", "cfg-if 1.0.0", - "event-listener 2.5.3", - "futures-lite", - "rustix 0.37.25", - "signal-hook", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.30", "windows-sys 0.48.0", ] [[package]] name = "async-rustls" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29479d362e242e320fa8f5c831940a5b83c1679af014068196cd20d4bf497b6b" +checksum = "ecfa55659849ace733f86ccd219da40abd8bc14124e40b312433e85a5a266e77" dependencies = [ "futures-io", "rustls", @@ -389,13 +412,31 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.3.0", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "rustix 0.38.30", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + [[package]] name = "async-sse" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53bba003996b8fd22245cd0c59b869ba764188ed435392cf2796d03b805ade10" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-std", "http-types", "log", @@ -410,16 +451,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-attributes", - "async-channel", + "async-channel 1.9.0", "async-global-executor", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite", + "futures-lite 1.13.0", "gloo-timers", "kv-log-macro", "log", @@ -433,26 +474,26 @@ dependencies = [ [[package]] name = "async-task" -version = "4.4.0" +version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] name = "atomic-waker" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" @@ -495,9 +536,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -537,9 +578,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "blake3" @@ -576,17 +617,18 @@ dependencies = [ [[package]] name = "blocking" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel", - "async-lock", + "async-channel 2.1.1", + "async-lock 3.3.0", "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "log", + "fastrand 2.0.1", + "futures-io", + "futures-lite 2.2.0", + "piper", + "tracing", ] [[package]] @@ -597,15 +639,15 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecount" -version = "0.6.3" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -648,9 +690,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", @@ -709,9 +751,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -719,9 +761,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -738,7 +780,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -761,18 +803,18 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_fn" @@ -782,18 +824,18 @@ checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] name = "const_format" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" dependencies = [ "proc-macro2", "quote", @@ -831,9 +873,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -841,15 +883,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -871,9 +913,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "criterion" @@ -911,48 +953,30 @@ dependencies = [ "itertools", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if 1.0.0", "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -995,9 +1019,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -1012,9 +1036,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] [[package]] name = "derive-new" @@ -1024,7 +1051,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -1090,9 +1117,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "dyn-clone" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "either" @@ -1111,9 +1138,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ "humantime", "is-terminal", @@ -1130,9 +1157,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.31" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" dependencies = [ "serde", ] @@ -1150,13 +1177,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1177,15 +1203,36 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", "pin-project-lite 0.2.13", ] +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite 0.2.13", +] + [[package]] name = "fancy-regex" version = "0.11.0" @@ -1205,6 +1252,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "femme" version = "2.2.1" @@ -1257,9 +1310,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1276,9 +1329,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1291,9 +1344,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1301,15 +1354,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1318,9 +1371,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1328,7 +1381,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -1337,34 +1390,47 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite 0.2.13", +] + [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1401,9 +1467,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1424,30 +1490,28 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git-version" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" dependencies = [ "git-version-macro", - "proc-macro-hack", ] [[package]] name = "git-version-macro" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ - "proc-macro-hack", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1470,9 +1534,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" dependencies = [ "bytes", "fnv", @@ -1480,7 +1544,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -1493,12 +1557,6 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.13.2" @@ -1510,9 +1568,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -1526,9 +1584,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1577,18 +1635,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1597,9 +1655,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1625,11 +1683,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" dependencies = [ "anyhow", - "async-channel", + "async-channel 1.9.0", "async-std", "base64 0.13.1", "cookie", - "futures-lite", + "futures-lite 1.13.0", "infer", "pin-project-lite 0.2.13", "rand 0.7.3", @@ -1660,9 +1718,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1675,7 +1733,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.4.9", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -1684,16 +1742,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows-core", ] [[package]] @@ -1707,9 +1765,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1717,22 +1775,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -1759,6 +1807,16 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "io-kit-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4769cb30e5dcf1710fc6730d3e94f78c47723a014a567de385e113c737394640" +dependencies = [ + "core-foundation-sys", + "mach2", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -1772,9 +1830,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "ipnetwork" @@ -1787,13 +1845,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ "hermit-abi", - "rustix 0.38.13", - "windows-sys 0.48.0", + "rustix 0.38.30", + "windows-sys 0.52.0", ] [[package]] @@ -1816,15 +1874,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -1848,12 +1906,12 @@ checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978" dependencies = [ "ahash", "anyhow", - "base64 0.21.4", + "base64 0.21.7", "bytecount", "clap", "fancy-regex", "fraction", - "getrandom 0.2.10", + "getrandom 0.2.12", "iso8601", "itoa", "memchr", @@ -1865,16 +1923,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "time 0.3.28", + "time 0.3.31", "url", "uuid", ] [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -1908,15 +1966,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if 1.0.0", "windows-sys 0.48.0", @@ -1924,9 +1982,20 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] [[package]] name = "linux-raw-sys" @@ -1936,15 +2005,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1962,36 +2031,27 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" dependencies = [ "twox-hash", ] -[[package]] -name = "mach" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9" -dependencies = [ - "libc", -] - [[package]] name = "mach2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ "libc", ] [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memoffset" @@ -2011,15 +2071,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.17" @@ -2043,9 +2094,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -2072,7 +2123,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] @@ -2107,7 +2158,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "cfg-if 1.0.0", "libc", ] @@ -2220,9 +2271,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", @@ -2240,18 +2291,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -2279,9 +2330,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.1.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "536900a8093134cf9ccf00a27deb3532421099e958d9dd431135d0c7543ca1e8" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" dependencies = [ "num-traits", ] @@ -2294,9 +2345,9 @@ checksum = "384e52fd8fbd4cbe3c317e8216260c21a0f9134de108cea8a4dd4e7e152c472d" [[package]] name = "parking" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -2310,13 +2361,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets 0.48.5", ] @@ -2329,11 +2380,11 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pem" -version = "2.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "serde", ] @@ -2348,15 +2399,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.3" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" dependencies = [ "memchr", "thiserror", @@ -2365,9 +2416,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.3" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" dependencies = [ "pest", "pest_generator", @@ -2375,26 +2426,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.3" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] name = "pest_meta" -version = "2.7.3" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" dependencies = [ "once_cell", "pest", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -2404,7 +2455,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.0", + "indexmap", ] [[package]] @@ -2424,7 +2475,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -2445,6 +2496,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -2539,7 +2601,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -2601,6 +2663,20 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "polling" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "pin-project-lite 0.2.13", + "rustix 0.38.30", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "polyval" version = "0.4.5" @@ -2612,6 +2688,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2626,9 +2708,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -2652,9 +2734,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13f81c9a9d574310b8351f8666f5a93ac3b0069c45c28ad52c10291389a7cf9" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand 0.8.5", @@ -2676,16 +2758,16 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", - "socket2 0.5.4", + "socket2 0.5.5", "tracing", "windows-sys 0.48.0", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2749,7 +2831,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] @@ -2763,9 +2845,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -2773,62 +2855,51 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "rcgen" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4954fbc00dcd4d8282c987710e50ba513d351400dbdd00e803a05172a90d8976" +checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" dependencies = [ "pem", "ring 0.16.20", - "time 0.3.28", + "time 0.3.31", "yasna", ] [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", + "getrandom 0.2.12", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -2838,9 +2909,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -2849,17 +2920,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -2878,6 +2949,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tower-service", "url", @@ -2904,12 +2976,12 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", - "getrandom 0.2.10", + "getrandom 0.2.12", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -2934,16 +3006,14 @@ checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e" [[package]] name = "rsa" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ - "byteorder", "const-oid", "digest 0.10.7", "num-bigint-dig", "num-integer", - "num-iter", "num-traits", "pkcs1", "pkcs8", @@ -2981,17 +3051,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.21", ] [[package]] name = "rustix" -version = "0.37.25" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", - "errno 0.3.3", + "errno 0.3.8", "io-lifetimes", "libc", "linux-raw-sys 0.3.8", @@ -3000,26 +3070,26 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.13" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.0", - "errno 0.3.3", + "bitflags 2.4.2", + "errno 0.3.8", "libc", - "linux-raw-sys 0.4.7", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.16.20", - "rustls-webpki 0.101.5", + "ring 0.17.7", + "rustls-webpki 0.101.7", "sct", ] @@ -3030,7 +3100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.3", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -3050,11 +3120,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", ] [[package]] @@ -3063,42 +3133,42 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb0a1f9b9efec70d32e6d6aa3e58ebd88c3754ec98dfe9145c63cf54cc829b83" +checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a" [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] name = "rustls-webpki" -version = "0.102.0" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89" +checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" dependencies = [ - "ring 0.17.6", + "ring 0.17.7", "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -3111,18 +3181,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.13" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -3132,9 +3202,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.13" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -3150,12 +3220,12 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -3202,9 +3272,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "semver-parser" @@ -3214,22 +3284,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -3254,9 +3324,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -3288,11 +3358,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.25" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" dependencies = [ - "indexmap 2.0.0", + "indexmap", "itoa", "ryu", "serde", @@ -3301,18 +3371,19 @@ dependencies = [ [[package]] name = "serialport" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c32634e2bd4311420caa504404a55fad2131292c485c97014cbed89a5899885f" +checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828" dependencies = [ - "CoreFoundation-sys", - "IOKit-sys", - "bitflags 1.3.2", + "bitflags 2.4.2", "cfg-if 1.0.0", + "core-foundation-sys", + "io-kit-sys", "mach2", "nix 0.26.4", "regex", "scopeguard", + "unescaper", "winapi", ] @@ -3327,9 +3398,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3357,9 +3428,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3398,16 +3469,6 @@ dependencies = [ "dirs", ] -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -3419,23 +3480,14 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", ] -[[package]] -name = "simple-mutex" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" -dependencies = [ - "event-listener 2.5.3", -] - [[package]] name = "slab" version = "0.4.9" @@ -3447,15 +3499,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -3463,9 +3515,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", @@ -3488,9 +3540,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -3566,7 +3618,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" dependencies = [ - "async-channel", + "async-channel 1.9.0", "cfg-if 1.0.0", "futures-core", "pin-project-lite 0.2.13", @@ -3586,15 +3638,15 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sval" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" +checksum = "1604e9ab506f4805bc62d2868c6d20f23fa6ced4c7cfe695a1d20589ba5c63d0" [[package]] name = "sval_buffer" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +checksum = "2831b6451148d344f612016d4277348f7721b78a0869a145fd34ef8b06b3fa2e" dependencies = [ "sval", "sval_ref", @@ -3602,18 +3654,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +checksum = "238ac5832a23099a413ffd22e66f7e6248b9af4581b64c758ca591074be059fc" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +checksum = "c8474862431bac5ac7aee8a12597798e944df33f489c340e17e886767bda0c4e" dependencies = [ "itoa", "ryu", @@ -3622,34 +3674,44 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +checksum = "d8f348030cc3d2a11eb534145600601f080cf16bf9ec0783efecd2883f14c21e" dependencies = [ "itoa", "ryu", "sval", ] +[[package]] +name = "sval_nested" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6659c3f6be1e5e99dc7c518877f48a8a39088ace2504b046db789bd78ce5969d" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + [[package]] name = "sval_ref" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +checksum = "829ad319bd82d0da77be6f3d547623686c453502f8eebdeb466cfa987972bd28" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" +checksum = "1a9da6c3efaedf8b8c0861ec5343e8e8c51d838f326478623328bd8728b79bca" dependencies = [ "serde", "sval", - "sval_buffer", - "sval_fmt", + "sval_nested", ] [[package]] @@ -3665,42 +3727,63 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -3743,21 +3826,22 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", + "powerfmt", "serde", "time-core", - "time-macros 0.2.14", + "time-macros 0.2.16", ] [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" @@ -3771,9 +3855,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -3827,9 +3911,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -3837,20 +3921,20 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite 0.2.13", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] @@ -3868,9 +3952,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", @@ -3880,9 +3964,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3900,11 +3984,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if 1.0.0", "log", "pin-project-lite 0.2.13", "tracing-attributes", @@ -3913,29 +3996,29 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" @@ -3950,7 +4033,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "sha1 0.10.5", + "sha1 0.10.6", "thiserror", "url", "utf-8", @@ -3968,9 +4051,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -3992,11 +4075,20 @@ dependencies = [ "spin 0.9.8", ] +[[package]] +name = "unescaper" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8f0f68e58d297ba8b22b8b5a96a87b863ba6bb46aaf51e19a4b02c5a6dd5b7f" +dependencies = [ + "thiserror", +] + [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -4070,9 +4162,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -4100,11 +4192,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.4.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] @@ -4133,9 +4225,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -4143,9 +4235,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" +checksum = "92cad98b1b18d06b6f38b3cd04347a9d7a3a0111441a061f71377fb6740437e4" dependencies = [ "erased-serde", "serde", @@ -4154,9 +4246,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" +checksum = "3dc7271d6b3bf58dd2e610a601c0e159f271ffdb7fbb21517c40b52138d64f8e" dependencies = [ "sval", "sval_buffer", @@ -4181,9 +4273,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "walkdir" @@ -4218,9 +4310,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if 1.0.0", "serde", @@ -4230,24 +4322,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -4257,9 +4349,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4267,28 +4359,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -4309,7 +4401,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" dependencies = [ - "windows 0.34.0", + "windows", ] [[package]] @@ -4330,9 +4422,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -4357,12 +4449,12 @@ dependencies = [ ] [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -4543,7 +4635,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.28", + "time 0.3.31", ] [[package]] @@ -4566,10 +4658,10 @@ dependencies = [ "async-global-executor", "async-std", "async-trait", - "base64 0.21.4", + "base64 0.21.7", "const_format", "env_logger", - "event-listener 4.0.0", + "event-listener 4.0.3", "flume", "form_urlencoded", "futures", @@ -4585,7 +4677,7 @@ dependencies = [ "rustc_version 0.4.0", "serde", "serde_json", - "socket2 0.5.4", + "socket2 0.5.5", "stop-token", "uhlc", "uuid", @@ -4738,7 +4830,7 @@ name = "zenoh-keyexpr" version = "0.11.0-dev" dependencies = [ "criterion", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "keyed-set", "lazy_static", "rand 0.8.5", @@ -4792,14 +4884,14 @@ dependencies = [ "async-rustls", "async-std", "async-trait", - "base64 0.21.4", + "base64 0.21.7", "futures", "log", "quinn", "rustls", "rustls-native-certs 0.7.0", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.0", + "rustls-webpki 0.102.1", "secrecy", "zenoh-config", "zenoh-core", @@ -4853,12 +4945,12 @@ dependencies = [ "async-rustls", "async-std", "async-trait", - "base64 0.21.4", + "base64 0.21.7", "futures", "log", "rustls", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.0", + "rustls-webpki 0.102.1", "secrecy", "webpki-roots", "zenoh-config", @@ -4877,7 +4969,7 @@ dependencies = [ "async-std", "async-trait", "log", - "socket2 0.5.4", + "socket2 0.5.5", "zenoh-buffers", "zenoh-collections", "zenoh-core", @@ -4893,7 +4985,7 @@ name = "zenoh-link-unixpipe" version = "0.11.0-dev" dependencies = [ "advisory-lock", - "async-io", + "async-io 1.13.0", "async-std", "async-trait", "filepath", @@ -4952,7 +5044,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 2.0.33", + "syn 2.0.48", "unzip-n", "zenoh-keyexpr", ] @@ -4982,7 +5074,7 @@ version = "0.11.0-dev" dependencies = [ "anyhow", "async-std", - "base64 0.21.4", + "base64 0.21.7", "clap", "const_format", "env_logger", @@ -5092,7 +5184,7 @@ name = "zenoh-sync" version = "0.11.0-dev" dependencies = [ "async-std", - "event-listener 4.0.0", + "event-listener 4.0.3", "flume", "futures", "tokio", @@ -5194,8 +5286,28 @@ dependencies = [ "zenoh_backend_traits", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 index 9461b9acce..58793df418 100644 --- a/plugin_test_config.json5 +++ b/plugin_test_config.json5 @@ -39,12 +39,8 @@ // { "plugins": { - // demonstrate "nof found" error - "not_found": { - }, // example plugin, see "plugins/zenog-plugin-example" - "example": { - }, + "example": {}, // rest plugin, see "plugins/zenoh-plugin-rest" "rest": { "http_port": 8080, @@ -53,15 +49,15 @@ // supports different backends implemented as plugins also "storage_manager": { backend_search_dirs: [ + "target/debug", "../zenoh-backend-influxdb/target/debug", ], "volumes": { // example backend, see "plugins/zenoh-backend-example" - "example": { - }, + "example": {}, // influxdb backend from "../zenoh-backend-influxdb" - "influxdb": { - }, + "influxdb": {}, + "influxdb2": {}, }, "storages": { "memory": { diff --git a/plugins/zenoh-backend-example/src/lib.rs b/plugins/zenoh-backend-example/src/lib.rs index 2d51e23dfc..36586e51f0 100644 --- a/plugins/zenoh-backend-example/src/lib.rs +++ b/plugins/zenoh-backend-example/src/lib.rs @@ -27,6 +27,7 @@ use zenoh_backend_traits::{ use zenoh_plugin_trait::{plugin_long_version, plugin_version, Plugin}; use zenoh_result::ZResult; +#[cfg(feature = "no_mangle")] zenoh_plugin_trait::declare_plugin!(ExampleBackend); impl Plugin for ExampleBackend { diff --git a/plugins/zenoh-plugin-example/src/lib.rs b/plugins/zenoh-plugin-example/src/lib.rs index ee07361ff9..c2f083827d 100644 --- a/plugins/zenoh-plugin-example/src/lib.rs +++ b/plugins/zenoh-plugin-example/src/lib.rs @@ -32,6 +32,7 @@ use zenoh_result::{bail, ZResult}; pub struct ExamplePlugin {} // declaration of the plugin's VTable for zenohd to find the plugin's functions to be called +#[cfg(feature = "no_mangle")] zenoh_plugin_trait::declare_plugin!(ExamplePlugin); // A default selector for this example of storage plugin (in case the config doesn't set it) diff --git a/plugins/zenoh-plugin-rest/src/lib.rs b/plugins/zenoh-plugin-rest/src/lib.rs index 56b619f0a8..6f4e80f4eb 100644 --- a/plugins/zenoh-plugin-rest/src/lib.rs +++ b/plugins/zenoh-plugin-rest/src/lib.rs @@ -189,7 +189,9 @@ fn response(status: StatusCode, content_type: impl TryInto, body: &str) -> builder.build() } +#[cfg(feature = "no_mangle")] zenoh_plugin_trait::declare_plugin!(RestPlugin); + pub struct RestPlugin {} #[derive(Clone, Copy, Debug)] struct StrError { diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 117779dba8..232aa0f9d1 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -52,7 +52,9 @@ mod memory_backend; mod replica; mod storages_mgt; +#[cfg(feature = "no_mangle")] zenoh_plugin_trait::declare_plugin!(StoragesPlugin); + pub struct StoragesPlugin {} impl ZenohPlugin for StoragesPlugin {} impl Plugin for StoragesPlugin { diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 7541c4a41a..a62fe7df09 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -276,17 +276,16 @@ impl PluginVTable { } } -/// This macro will add a non-mangled functions which provides plugin version and loads it if feature `no_mangle` is enabled in the destination crate. +/// This macro will add a non-mangled functions which provides plugin version and loads it into the host. +/// If plugin library should work also as static, consider calling this macro under feature condition #[macro_export] macro_rules! declare_plugin { ($ty: path) => { - #[cfg(feature = "no_mangle")] #[no_mangle] fn get_plugin_loader_version() -> $crate::PluginLoaderVersion { $crate::PLUGIN_LOADER_VERSION } - #[cfg(feature = "no_mangle")] #[no_mangle] fn get_compatibility() -> $crate::Compatibility { $crate::Compatibility::with_plugin_version::< @@ -296,7 +295,6 @@ macro_rules! declare_plugin { >() } - #[cfg(feature = "no_mangle")] #[no_mangle] fn load_plugin() -> $crate::PluginVTable< <$ty as $crate::Plugin>::StartArgs, From 48060b9c81d6a53609759cb7c3c76557ab2c4595 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Wed, 17 Jan 2024 19:20:53 +0100 Subject: [PATCH 096/106] all plugins covered in test config --- plugin_test_config.json5 | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 index 58793df418..e0710c8b19 100644 --- a/plugin_test_config.json5 +++ b/plugin_test_config.json5 @@ -35,10 +35,29 @@ // cd zenoh // RUST_LOG=info cargo run -- --config plugin_test_config.json5 // ``` -// +// +// Loading plugin errors are expected due to some mandtatory properties missing in the config file, like for "influxdb" and "influxdb2" volumes. +// Though there should not be plugin loading errors due to not found files or version incompatibility // { + "plugins_search_dirs": [ + "target/debug", + "../zenoh-plugin-webserver/target/debug", + "../zenoh-plugin-mqtt/target/debug", + "../zenoh-plugin-dds/target/debug", + "../zenoh-plugin-ros1/target/debug", + "../zenoh-plugin-ros2dds/target/debug" + ], + "plugins": { + // mqtt plugin, see "../zenoh-plugin-mqtt" + "mqtt": {}, + // dds plugin, see "../zenoh-plugin-dds" + "dds": {}, + // ros1 plugin, see "../zenoh-plugin-ros1" + "ros1": {}, + // ros2dds plugin, see "../zenoh-plugin-ros2dds" + "ros2dds": {}, // example plugin, see "plugins/zenog-plugin-example" "example": {}, // rest plugin, see "plugins/zenoh-plugin-rest" @@ -51,13 +70,20 @@ backend_search_dirs: [ "target/debug", "../zenoh-backend-influxdb/target/debug", + "../zenoh-backend-rocksdb/target/debug", + "../zenoh-backend-filesystem/target/debug" ], "volumes": { // example backend, see "plugins/zenoh-backend-example" "example": {}, - // influxdb backend from "../zenoh-backend-influxdb" + // influxdb backend from "../zenoh-backend-influxdb/v1" "influxdb": {}, + // influxdb backend from "../zenoh-backend-influxdb/v2" "influxdb2": {}, + // rocksdb backend, see "plugins/zenoh-backend-rocksdb" + "rocksdb": {}, + // filesystem backend, see "plugins/zenoh-backend-filesystem" + "fs": {} }, "storages": { "memory": { @@ -70,8 +96,5 @@ }, } }, - "dds": { - "__path__": ["../zenoh-plugin-dds/target/debug/libzenoh_plugin_dds.so","../zenoh-plugin-dds/target/debug/libzenoh_plugin_dds.dylib"], - } } } From 31cacc11e9107c5b2dc0c447603b3e789fc67e3e Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 18 Jan 2024 13:54:07 +0100 Subject: [PATCH 097/106] comments update --- plugin_test_config.json5 | 46 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 index e0710c8b19..d6c430cc3e 100644 --- a/plugin_test_config.json5 +++ b/plugin_test_config.json5 @@ -2,7 +2,7 @@ // // To run it do these steps: // -// - Clone these repositories: +// 1. Clone these repositories: // ``` // git clone https://github.com/eclipse-zenoh/zenoh.git // git clone https://github.com/eclipse-zenoh/zenoh-backend-influxdb.git @@ -15,30 +15,60 @@ // git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git // ``` // -// - Init submodules for zenoh-plugin-ros1 +// 1.1. Init submodules for zenoh-plugin-ros1 // ``` // cd zenoh-plugin-ros1 // git submodule init // git submodule update // ``` // -// - Build projects +// 2. Build projects // ``` // cd zenoh && cargo build && cd .. // cd zenoh-backend-influxdb && cargo build && cd .. // ... // ``` // -// - Run the zenohd server with this config file. -// Explicit setting RUST_LOG=info is important: without it the logs with default le are printed by zenohd itsellf, but not by plugins. +// 3. Run the zenohd server with this config file. +// +// Explicit setting RUST_LOG=info is important: without it the logs are printed by zenohd itsellf, but not by plugins. // ``` // cd zenoh // RUST_LOG=info cargo run -- --config plugin_test_config.json5 // ``` // -// Loading plugin errors are expected due to some mandtatory properties missing in the config file, like for "influxdb" and "influxdb2" volumes. -// Though there should not be plugin loading errors due to not found files or version incompatibility -// +// Some errors on plugin initalisation are expected due to some mandtatory properties missing in the config file, like for "influxdb" and "influxdb2" volumes. +// Though there supposedly should not be plugin loading errors due to not found files or version incompatibility +// +// +// 4. Test access plugin status through admin space +// +// The plugins information is available by "@/router/{router_id}/plugins/**". Each plugin provides by this key the json object with its status. +// Subplugins are also available by this key, e.g. "@/router/{router_id}/plugins/storage_manager/influxdb". +// ``` +// cargo run --example z_get -- -s "@/router/*/plugins/**" +// ``` +// result is +// ``` +// Received ('@/router/b04a929103101296abec19ea6cddd034/plugins/example': '{"long_version":"v0.11.0-dev-182-g48060b9c","name":"example","path":"/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_example.dylib","report":{"level":"Normal"},"state":"Started","version":"0.11.0-dev"}') +/// Received ('@/router/b04a929103101296abec19ea6cddd034/plugins/storage_manager': '{"long_version":"v0.11.0-dev-182-g48060b9c","name":"storage_manager","path":"/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_storage_manager.dylib","report":{"level":"Normal"},"state":"Started","version":"0.11.0-dev"}') +/// Received ('@/router/b04a929103101296abec19ea6cddd034/plugins/storage_manager/memory': '{"long_version":"v0.11.0-dev-182-g48060b9c","name":"storage_manager/memory","path":"","report":{"level":"Normal"},"state":"Started","version":"0.11.0-dev"}') +// ... +// ``` +// +// There is also plugin information by path "@/router/*/status/plugins/**". Later these paths should be combined +// ``` +// cargo run --example z_get -- -s "@/router/*/status/plugins/**" +// ``` +// result is +// ``` +// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/example/__path__': '/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_example.dylib') +// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/__path__': '/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_storage_manager.dylib') +// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/volumes/memory/__path__': '""') +// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/volumes/memory': '{"__required__":false}') +// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/storages/memory': '{"key_expr":"demo/memory/**","volume":"memory"}') +// ``` +// { "plugins_search_dirs": [ "target/debug", From 95234a4f1e364f1aa41051cddef358af9633ad37 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 18 Jan 2024 14:00:56 +0100 Subject: [PATCH 098/106] cargo fmt --- .../zenoh-plugin-storage-manager/src/lib.rs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 232aa0f9d1..b1f1e15da7 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -133,16 +133,27 @@ impl StorageRuntimeInner { required: false, rest: Default::default(), }) - .map_or_else(|e| log::error!("Cannot spawn static volume '{}': {}", MEMORY_BACKEND_NAME, e), |_| ()); + .map_or_else( + |e| { + log::error!( + "Cannot spawn static volume '{}': {}", + MEMORY_BACKEND_NAME, + e + ) + }, + |_| (), + ); for volume in &volumes { - new_self - .spawn_volume(volume) - .map_or_else(|e| log::error!("Cannot spawn volume '{}': {}", volume.name(), e), |_| ()); + new_self.spawn_volume(volume).map_or_else( + |e| log::error!("Cannot spawn volume '{}': {}", volume.name(), e), + |_| (), + ); } for storage in &storages { - new_self - .spawn_storage(storage) - .map_or_else(|e| log::error!("Cannot spawn storage '{}': {}", storage.name(), e), |_| ()); + new_self.spawn_storage(storage).map_or_else( + |e| log::error!("Cannot spawn storage '{}': {}", storage.name(), e), + |_| (), + ); } Ok(new_self) } From 9f36a027f65c7627782e97f69e8b904bad804e3a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 18 Jan 2024 14:23:26 +0100 Subject: [PATCH 099/106] restored cargo.lock --- Cargo.lock | 1258 ++++++++++++++++++++++++---------------------------- 1 file changed, 573 insertions(+), 685 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9c7ba2fea..a03e85fd79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,27 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "CoreFoundation-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b" +dependencies = [ + "libc", + "mach", +] + +[[package]] +name = "IOKit-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a" +dependencies = [ + "CoreFoundation-sys", + "libc", + "mach", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -94,23 +115,22 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.12", + "getrandom 0.2.10", "once_cell", "serde", "version_check", - "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -144,9 +164,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.8" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628a8f9bd1e24b4e0db2b4bc2d000b001e7dd032d54afa60a68836aeec5aa54a" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -158,26 +178,26 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -192,9 +212,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "array-init" @@ -235,70 +255,56 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-channel" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" -dependencies = [ - "concurrent-queue", - "event-listener 4.0.3", - "event-listener-strategy", - "futures-core", - "pin-project-lite 0.2.13", -] - [[package]] name = "async-dup" -version = "1.2.4" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2886ab563af5038f79ec016dd7b87947ed138b794e8dd64992962c9cca0411" +checksum = "7427a12b8dc09291528cfb1da2447059adb4a257388c2acd6497a79d55cf6f7c" dependencies = [ - "async-lock 3.3.0", "futures-io", + "simple-mutex", ] [[package]] name = "async-executor" -version = "1.8.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" dependencies = [ - "async-lock 3.3.0", + "async-lock", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.2.0", + "fastrand", + "futures-lite", "slab", ] [[package]] name = "async-global-executor" -version = "2.4.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" dependencies = [ - "async-channel 2.1.1", + "async-channel", "async-executor", - "async-io 2.3.0", - "async-lock 3.3.0", + "async-io", + "async-lock", "blocking", - "futures-lite 2.2.0", + "futures-lite", "once_cell", "tokio", ] [[package]] name = "async-h1" -version = "2.3.4" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1d1dae8cb2c4258a79d6ed088b7fb9b4763bf4e9b22d040779761e046a2971" +checksum = "8101020758a4fc3a7c326cb42aa99e9fa77cbfb76987c128ad956406fe1f70a7" dependencies = [ - "async-channel 1.9.0", + "async-channel", "async-dup", - "async-global-executor", - "async-io 1.13.0", - "futures-lite 1.13.0", + "async-std", + "futures-core", "http-types", "httparse", "log", @@ -311,39 +317,20 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock 2.8.0", + "async-lock", "autocfg", "cfg-if 1.0.0", "concurrent-queue", - "futures-lite 1.13.0", + "futures-lite", "log", "parking", - "polling 2.8.0", - "rustix 0.37.27", + "polling", + "rustix 0.37.25", "slab", - "socket2 0.4.10", + "socket2 0.4.9", "waker-fn", ] -[[package]] -name = "async-io" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744" -dependencies = [ - "async-lock 3.3.0", - "cfg-if 1.0.0", - "concurrent-queue", - "futures-io", - "futures-lite 2.2.0", - "parking", - "polling 3.3.2", - "rustix 0.38.30", - "slab", - "tracing", - "windows-sys 0.52.0", -] - [[package]] name = "async-lock" version = "2.8.0" @@ -353,39 +340,29 @@ dependencies = [ "event-listener 2.5.3", ] -[[package]] -name = "async-lock" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" -dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy", - "pin-project-lite 0.2.13", -] - [[package]] name = "async-process" -version = "1.8.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", - "async-signal", + "async-io", + "async-lock", + "autocfg", "blocking", "cfg-if 1.0.0", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.30", + "event-listener 2.5.3", + "futures-lite", + "rustix 0.37.25", + "signal-hook", "windows-sys 0.48.0", ] [[package]] name = "async-rustls" -version = "0.4.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfa55659849ace733f86ccd219da40abd8bc14124e40b312433e85a5a266e77" +checksum = "29479d362e242e320fa8f5c831940a5b83c1679af014068196cd20d4bf497b6b" dependencies = [ "futures-io", "rustls", @@ -412,31 +389,13 @@ dependencies = [ "sha2 0.9.9", ] -[[package]] -name = "async-signal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" -dependencies = [ - "async-io 2.3.0", - "async-lock 2.8.0", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix 0.38.30", - "signal-hook-registry", - "slab", - "windows-sys 0.48.0", -] - [[package]] name = "async-sse" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53bba003996b8fd22245cd0c59b869ba764188ed435392cf2796d03b805ade10" dependencies = [ - "async-channel 1.9.0", + "async-channel", "async-std", "http-types", "log", @@ -451,16 +410,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-attributes", - "async-channel 1.9.0", + "async-channel", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", + "futures-lite", "gloo-timers", "kv-log-macro", "log", @@ -474,26 +433,26 @@ dependencies = [ [[package]] name = "async-task" -version = "4.7.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] name = "atomic-waker" -version = "1.1.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" [[package]] name = "autocfg" @@ -536,9 +495,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.7" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -578,9 +537,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "blake3" @@ -617,18 +576,17 @@ dependencies = [ [[package]] name = "blocking" -version = "1.5.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" dependencies = [ - "async-channel 2.1.1", - "async-lock 3.3.0", + "async-channel", + "async-lock", "async-task", - "fastrand 2.0.1", - "futures-io", - "futures-lite 2.2.0", - "piper", - "tracing", + "atomic-waker", + "fastrand", + "futures-lite", + "log", ] [[package]] @@ -639,15 +597,15 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" @@ -690,9 +648,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", @@ -751,9 +709,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -761,9 +719,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -780,7 +738,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -803,18 +761,18 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" dependencies = [ "crossbeam-utils", ] [[package]] name = "const-oid" -version = "0.9.6" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "const_fn" @@ -824,18 +782,18 @@ checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" dependencies = [ "proc-macro2", "quote", @@ -873,9 +831,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -883,15 +841,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -913,9 +871,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "criterion" @@ -953,30 +911,48 @@ dependencies = [ "itertools", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ + "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ + "autocfg", + "cfg-if 1.0.0", "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if 1.0.0", +] [[package]] name = "crypto-common" @@ -1019,9 +995,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der" @@ -1036,12 +1012,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" [[package]] name = "derive-new" @@ -1051,7 +1024,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -1117,9 +1090,9 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "dyn-clone" -version = "1.0.16" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" +checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" [[package]] name = "either" @@ -1138,9 +1111,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", "is-terminal", @@ -1157,9 +1130,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.4.2" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" dependencies = [ "serde", ] @@ -1177,12 +1150,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ + "errno-dragonfly", "libc", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -1203,36 +1177,15 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.1.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" dependencies = [ "concurrent-queue", "parking", "pin-project-lite 0.2.13", ] -[[package]] -name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite 0.2.13", -] - [[package]] name = "fancy-regex" version = "0.11.0" @@ -1252,12 +1205,6 @@ dependencies = [ "instant", ] -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - [[package]] name = "femme" version = "2.2.1" @@ -1310,9 +1257,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -1329,9 +1276,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -1344,9 +1291,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -1354,15 +1301,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -1371,9 +1318,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" @@ -1381,7 +1328,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand 1.9.0", + "fastrand", "futures-core", "futures-io", "memchr", @@ -1390,47 +1337,34 @@ dependencies = [ "waker-fn", ] -[[package]] -name = "futures-lite" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" -dependencies = [ - "fastrand 2.0.1", - "futures-core", - "futures-io", - "parking", - "pin-project-lite 0.2.13", -] - [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -1467,9 +1401,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1490,28 +1424,30 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "git-version" -version = "0.3.9" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" dependencies = [ "git-version-macro", + "proc-macro-hack", ] [[package]] name = "git-version-macro" -version = "0.3.9" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" dependencies = [ + "proc-macro-hack", "proc-macro2", "quote", - "syn 2.0.48", + "syn 1.0.109", ] [[package]] @@ -1534,9 +1470,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.23" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1544,7 +1480,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -1557,6 +1493,12 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.13.2" @@ -1568,9 +1510,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" dependencies = [ "ahash", "allocator-api2", @@ -1584,9 +1526,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -1635,18 +1577,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "http" -version = "0.2.11" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -1655,9 +1597,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -1683,11 +1625,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" dependencies = [ "anyhow", - "async-channel 1.9.0", + "async-channel", "async-std", "base64 0.13.1", "cookie", - "futures-lite 1.13.0", + "futures-lite", "infer", "pin-project-lite 0.2.13", "rand 0.7.3", @@ -1718,9 +1660,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -1733,7 +1675,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.5.5", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -1742,16 +1684,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows 0.48.0", ] [[package]] @@ -1765,9 +1707,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1775,12 +1717,22 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.0", ] [[package]] @@ -1807,16 +1759,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "io-kit-sys" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4769cb30e5dcf1710fc6730d3e94f78c47723a014a567de385e113c737394640" -dependencies = [ - "core-foundation-sys", - "mach2", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -1830,9 +1772,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "ipnetwork" @@ -1845,13 +1787,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.30", - "windows-sys 0.52.0", + "rustix 0.38.13", + "windows-sys 0.48.0", ] [[package]] @@ -1874,15 +1816,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1906,12 +1848,12 @@ checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978" dependencies = [ "ahash", "anyhow", - "base64 0.21.7", + "base64 0.21.4", "bytecount", "clap", "fancy-regex", "fraction", - "getrandom 0.2.12", + "getrandom 0.2.10", "iso8601", "itoa", "memchr", @@ -1923,16 +1865,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "time 0.3.31", + "time 0.3.28", "url", "uuid", ] [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -1966,15 +1908,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" dependencies = [ "cfg-if 1.0.0", "windows-sys 0.48.0", @@ -1982,20 +1924,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "libredox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" -dependencies = [ - "bitflags 2.4.2", - "libc", - "redox_syscall", -] +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linux-raw-sys" @@ -2005,15 +1936,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -2031,27 +1962,36 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" +checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" dependencies = [ "twox-hash", ] +[[package]] +name = "mach" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9" +dependencies = [ + "libc", +] + [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" dependencies = [ "libc", ] [[package]] name = "memchr" -version = "2.7.1" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memoffset" @@ -2071,6 +2011,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -2094,9 +2043,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", @@ -2123,7 +2072,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.10", ] [[package]] @@ -2158,7 +2107,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.4.0", "cfg-if 1.0.0", "libc", ] @@ -2271,9 +2220,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", "libm", @@ -2291,18 +2240,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" @@ -2330,9 +2279,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.2.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +checksum = "536900a8093134cf9ccf00a27deb3532421099e958d9dd431135d0c7543ca1e8" dependencies = [ "num-traits", ] @@ -2345,9 +2294,9 @@ checksum = "384e52fd8fbd4cbe3c317e8216260c21a0f9134de108cea8a4dd4e7e152c472d" [[package]] name = "parking" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "parking_lot" @@ -2361,13 +2310,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", "windows-targets 0.48.5", ] @@ -2380,11 +2329,11 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pem" -version = "3.0.3" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" dependencies = [ - "base64 0.21.7", + "base64 0.21.4", "serde", ] @@ -2399,15 +2348,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" dependencies = [ "memchr", "thiserror", @@ -2416,9 +2365,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" dependencies = [ "pest", "pest_generator", @@ -2426,26 +2375,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" dependencies = [ "once_cell", "pest", - "sha2 0.10.8", + "sha2 0.10.7", ] [[package]] @@ -2455,7 +2404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 2.0.0", ] [[package]] @@ -2475,7 +2424,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -2496,17 +2445,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" -dependencies = [ - "atomic-waker", - "fastrand 2.0.1", - "futures-io", -] - [[package]] name = "pkcs1" version = "0.7.5" @@ -2601,7 +2539,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -2663,20 +2601,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "polling" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" -dependencies = [ - "cfg-if 1.0.0", - "concurrent-queue", - "pin-project-lite 0.2.13", - "rustix 0.38.30", - "tracing", - "windows-sys 0.52.0", -] - [[package]] name = "polyval" version = "0.4.5" @@ -2688,12 +2612,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2708,9 +2626,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -2734,9 +2652,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.6" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +checksum = "e13f81c9a9d574310b8351f8666f5a93ac3b0069c45c28ad52c10291389a7cf9" dependencies = [ "bytes", "rand 0.8.5", @@ -2758,16 +2676,16 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", - "socket2 0.5.5", + "socket2 0.5.4", "tracing", "windows-sys 0.48.0", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2831,7 +2749,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.10", ] [[package]] @@ -2845,9 +2763,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -2855,51 +2773,62 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ + "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", + "num_cpus", ] [[package]] name = "rcgen" -version = "0.11.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" +checksum = "4954fbc00dcd4d8282c987710e50ba513d351400dbdd00e803a05172a90d8976" dependencies = [ "pem", "ring 0.16.20", - "time 0.3.31", + "time 0.3.28", "yasna", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.12", - "libredox", + "getrandom 0.2.10", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", @@ -2909,9 +2838,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -2920,17 +2849,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.7", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -2949,7 +2878,6 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "system-configuration", "tokio", "tower-service", "url", @@ -2976,12 +2904,12 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" dependencies = [ "cc", - "getrandom 0.2.12", + "getrandom 0.2.10", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -3006,14 +2934,16 @@ checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e" [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ + "byteorder", "const-oid", "digest 0.10.7", "num-bigint-dig", "num-integer", + "num-iter", "num-traits", "pkcs1", "pkcs8", @@ -3051,17 +2981,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.18", ] [[package]] name = "rustix" -version = "0.37.27" +version = "0.37.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" dependencies = [ "bitflags 1.3.2", - "errno 0.3.8", + "errno 0.3.3", "io-lifetimes", "libc", "linux-raw-sys 0.3.8", @@ -3070,26 +3000,26 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags 2.4.2", - "errno 0.3.8", + "bitflags 2.4.0", + "errno 0.3.3", "libc", - "linux-raw-sys 0.4.13", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.7", + "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", - "ring 0.17.7", - "rustls-webpki 0.101.7", + "ring 0.16.20", + "rustls-webpki 0.101.5", "sct", ] @@ -3100,7 +3030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.4", + "rustls-pemfile 1.0.3", "schannel", "security-framework", ] @@ -3120,11 +3050,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.7", + "base64 0.21.4", ] [[package]] @@ -3133,42 +3063,42 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" dependencies = [ - "base64 0.21.7", + "base64 0.21.4", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.1.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a" +checksum = "eb0a1f9b9efec70d32e6d6aa3e58ebd88c3754ec98dfe9145c63cf54cc829b83" [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.101.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] name = "rustls-webpki" -version = "0.102.1" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89" dependencies = [ - "ring 0.17.7", + "ring 0.17.6", "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -3181,18 +3111,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "schemars" -version = "0.8.16" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" dependencies = [ "dyn-clone", "schemars_derive", @@ -3202,9 +3132,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.16" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" dependencies = [ "proc-macro2", "quote", @@ -3220,12 +3150,12 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3272,9 +3202,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "semver-parser" @@ -3284,22 +3214,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -3324,9 +3254,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -3358,11 +3288,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.30" +version = "0.9.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" dependencies = [ - "indexmap", + "indexmap 2.0.0", "itoa", "ryu", "serde", @@ -3371,19 +3301,18 @@ dependencies = [ [[package]] name = "serialport" -version = "4.3.0" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828" +checksum = "c32634e2bd4311420caa504404a55fad2131292c485c97014cbed89a5899885f" dependencies = [ - "bitflags 2.4.2", + "CoreFoundation-sys", + "IOKit-sys", + "bitflags 1.3.2", "cfg-if 1.0.0", - "core-foundation-sys", - "io-kit-sys", "mach2", "nix 0.26.4", "regex", "scopeguard", - "unescaper", "winapi", ] @@ -3398,9 +3327,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3428,9 +3357,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -3469,6 +3398,16 @@ dependencies = [ "dirs", ] +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -3480,14 +3419,23 @@ dependencies = [ [[package]] name = "signature" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simple-mutex" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" +dependencies = [ + "event-listener 2.5.3", +] + [[package]] name = "slab" version = "0.4.9" @@ -3499,15 +3447,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -3515,9 +3463,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys 0.48.0", @@ -3540,9 +3488,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -3618,7 +3566,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" dependencies = [ - "async-channel 1.9.0", + "async-channel", "cfg-if 1.0.0", "futures-core", "pin-project-lite 0.2.13", @@ -3638,15 +3586,15 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sval" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604e9ab506f4805bc62d2868c6d20f23fa6ced4c7cfe695a1d20589ba5c63d0" +checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" [[package]] name = "sval_buffer" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2831b6451148d344f612016d4277348f7721b78a0869a145fd34ef8b06b3fa2e" +checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" dependencies = [ "sval", "sval_ref", @@ -3654,18 +3602,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238ac5832a23099a413ffd22e66f7e6248b9af4581b64c758ca591074be059fc" +checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8474862431bac5ac7aee8a12597798e944df33f489c340e17e886767bda0c4e" +checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" dependencies = [ "itoa", "ryu", @@ -3674,44 +3622,34 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f348030cc3d2a11eb534145600601f080cf16bf9ec0783efecd2883f14c21e" +checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" dependencies = [ "itoa", "ryu", "sval", ] -[[package]] -name = "sval_nested" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6659c3f6be1e5e99dc7c518877f48a8a39088ace2504b046db789bd78ce5969d" -dependencies = [ - "sval", - "sval_buffer", - "sval_ref", -] - [[package]] name = "sval_ref" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829ad319bd82d0da77be6f3d547623686c453502f8eebdeb466cfa987972bd28" +checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.11.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9da6c3efaedf8b8c0861ec5343e8e8c51d838f326478623328bd8728b79bca" +checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" dependencies = [ "serde", "sval", - "sval_nested", + "sval_buffer", + "sval_fmt", ] [[package]] @@ -3727,63 +3665,42 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "termcolor" -version = "1.4.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -3826,22 +3743,21 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", - "powerfmt", "serde", "time-core", - "time-macros 0.2.16", + "time-macros 0.2.14", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" @@ -3855,9 +3771,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -3911,9 +3827,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.35.1" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "bytes", @@ -3921,20 +3837,20 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite 0.2.13", - "socket2 0.5.5", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] @@ -3952,9 +3868,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" dependencies = [ "futures-util", "log", @@ -3964,9 +3880,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -3984,10 +3900,11 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ + "cfg-if 1.0.0", "log", "pin-project-lite 0.2.13", "tracing-attributes", @@ -3996,29 +3913,29 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" @@ -4033,7 +3950,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "sha1 0.10.6", + "sha1 0.10.5", "thiserror", "url", "utf-8", @@ -4051,9 +3968,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -4075,20 +3992,11 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "unescaper" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f0f68e58d297ba8b22b8b5a96a87b863ba6bb46aaf51e19a4b02c5a6dd5b7f" -dependencies = [ - "thiserror", -] - [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" @@ -4162,9 +4070,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -4192,11 +4100,11 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.10", ] [[package]] @@ -4225,9 +4133,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.6.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" +checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -4235,9 +4143,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.6.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92cad98b1b18d06b6f38b3cd04347a9d7a3a0111441a061f71377fb6740437e4" +checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" dependencies = [ "erased-serde", "serde", @@ -4246,9 +4154,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.6.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc7271d6b3bf58dd2e610a601c0e159f271ffdb7fbb21517c40b52138d64f8e" +checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" dependencies = [ "sval", "sval_buffer", @@ -4273,9 +4181,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" @@ -4310,9 +4218,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "serde", @@ -4322,24 +4230,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -4349,9 +4257,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4359,28 +4267,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.33", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -4401,7 +4309,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" dependencies = [ - "windows", + "windows 0.34.0", ] [[package]] @@ -4422,9 +4330,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] @@ -4449,12 +4357,12 @@ dependencies = [ ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.48.5", ] [[package]] @@ -4635,7 +4543,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.31", + "time 0.3.28", ] [[package]] @@ -4658,10 +4566,10 @@ dependencies = [ "async-global-executor", "async-std", "async-trait", - "base64 0.21.7", + "base64 0.21.4", "const_format", "env_logger", - "event-listener 4.0.3", + "event-listener 4.0.0", "flume", "form_urlencoded", "futures", @@ -4677,7 +4585,7 @@ dependencies = [ "rustc_version 0.4.0", "serde", "serde_json", - "socket2 0.5.5", + "socket2 0.5.4", "stop-token", "uhlc", "uuid", @@ -4830,7 +4738,7 @@ name = "zenoh-keyexpr" version = "0.11.0-dev" dependencies = [ "criterion", - "hashbrown 0.14.3", + "hashbrown 0.14.0", "keyed-set", "lazy_static", "rand 0.8.5", @@ -4884,14 +4792,14 @@ dependencies = [ "async-rustls", "async-std", "async-trait", - "base64 0.21.7", + "base64 0.21.4", "futures", "log", "quinn", "rustls", "rustls-native-certs 0.7.0", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.1", + "rustls-webpki 0.102.0", "secrecy", "zenoh-config", "zenoh-core", @@ -4945,12 +4853,12 @@ dependencies = [ "async-rustls", "async-std", "async-trait", - "base64 0.21.7", + "base64 0.21.4", "futures", "log", "rustls", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.1", + "rustls-webpki 0.102.0", "secrecy", "webpki-roots", "zenoh-config", @@ -4969,7 +4877,7 @@ dependencies = [ "async-std", "async-trait", "log", - "socket2 0.5.5", + "socket2 0.5.4", "zenoh-buffers", "zenoh-collections", "zenoh-core", @@ -4985,7 +4893,7 @@ name = "zenoh-link-unixpipe" version = "0.11.0-dev" dependencies = [ "advisory-lock", - "async-io 1.13.0", + "async-io", "async-std", "async-trait", "filepath", @@ -5044,7 +4952,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 2.0.48", + "syn 2.0.33", "unzip-n", "zenoh-keyexpr", ] @@ -5074,7 +4982,7 @@ version = "0.11.0-dev" dependencies = [ "anyhow", "async-std", - "base64 0.21.7", + "base64 0.21.4", "clap", "const_format", "env_logger", @@ -5184,7 +5092,7 @@ name = "zenoh-sync" version = "0.11.0-dev" dependencies = [ "async-std", - "event-listener 4.0.3", + "event-listener 4.0.0", "flume", "futures", "tokio", @@ -5286,28 +5194,8 @@ dependencies = [ "zenoh_backend_traits", ] -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "zeroize" -version = "1.7.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" From be24a42d469c1daeb64a70040dc0f065afe6e001 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 18 Jan 2024 14:29:11 +0100 Subject: [PATCH 100/106] undo changes in DEFAULT_CONFIG --- DEFAULT_CONFIG.json5 | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index 4321c3fcc7..bde1b8fd03 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -406,18 +406,14 @@ // }, // }, - /// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // }, - // not_found: { - // }, - // example: { - // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } // }, } From 3b10fd73ef0ffe423d562a25887c8a157308b96a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 18 Jan 2024 15:19:51 +0100 Subject: [PATCH 101/106] compatibility code in separate .rs, minor changes --- plugins/zenoh-backend-traits/src/config.rs | 6 +- plugins/zenoh-backend-traits/src/lib.rs | 4 +- .../zenoh-plugin-trait/src/compatibility.rs | 258 ++++++++++++++++++ plugins/zenoh-plugin-trait/src/lib.rs | 6 +- plugins/zenoh-plugin-trait/src/plugin.rs | 15 +- plugins/zenoh-plugin-trait/src/vtable.rs | 239 +--------------- zenoh/src/net/runtime/adminspace.rs | 2 +- zenoh/src/net/runtime/mod.rs | 4 +- zenoh/src/plugins/sealed.rs | 4 +- 9 files changed, 279 insertions(+), 259 deletions(-) create mode 100644 plugins/zenoh-plugin-trait/src/compatibility.rs diff --git a/plugins/zenoh-backend-traits/src/config.rs b/plugins/zenoh-backend-traits/src/config.rs index f2f05a8eef..dbcfa420b3 100644 --- a/plugins/zenoh-backend-traits/src/config.rs +++ b/plugins/zenoh-backend-traits/src/config.rs @@ -1,4 +1,3 @@ -use const_format::concatcp; // // Copyright (c) 2023 ZettaScale Technology // @@ -12,13 +11,14 @@ use const_format::concatcp; // Contributors: // ZettaScale Zenoh Team, // +use const_format::concatcp; use derive_more::{AsMut, AsRef}; use schemars::JsonSchema; use serde_json::{Map, Value}; use std::convert::TryFrom; use std::time::Duration; use zenoh::{key_expr::keyexpr, prelude::OwnedKeyExpr, Result as ZResult}; -use zenoh_plugin_trait::{PluginStartArgs, PluginStructVersion}; +use zenoh_plugin_trait::{PluginStartArgs, StructVersion}; use zenoh_result::{bail, zerror, Error}; #[derive(JsonSchema, Debug, Clone, AsMut, AsRef)] @@ -69,7 +69,7 @@ pub struct ReplicaConfig { pub delta: Duration, } -impl PluginStructVersion for VolumeConfig { +impl StructVersion for VolumeConfig { fn struct_version() -> u64 { 1 } diff --git a/plugins/zenoh-backend-traits/src/lib.rs b/plugins/zenoh-backend-traits/src/lib.rs index 16aad432d7..8b9fa359e0 100644 --- a/plugins/zenoh-backend-traits/src/lib.rs +++ b/plugins/zenoh-backend-traits/src/lib.rs @@ -141,7 +141,7 @@ use zenoh::queryable::ReplyBuilder; use zenoh::time::Timestamp; use zenoh::value::Value; pub use zenoh::Result as ZResult; -use zenoh_plugin_trait::{PluginControl, PluginInstance, PluginStatusRec, PluginStructVersion}; +use zenoh_plugin_trait::{PluginControl, PluginInstance, PluginStatusRec, StructVersion}; use zenoh_util::concat_enabled_features; pub mod config; @@ -222,7 +222,7 @@ pub trait Volume: Send + Sync { pub type VolumeInstance = Box; -impl PluginStructVersion for VolumeInstance { +impl StructVersion for VolumeInstance { fn struct_version() -> u64 { 1 } diff --git a/plugins/zenoh-plugin-trait/src/compatibility.rs b/plugins/zenoh-plugin-trait/src/compatibility.rs new file mode 100644 index 0000000000..2887270a85 --- /dev/null +++ b/plugins/zenoh-plugin-trait/src/compatibility.rs @@ -0,0 +1,258 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::fmt::Display; + +use crate::{Plugin, PluginInstance, PluginStartArgs, PluginVTable}; + +pub trait StructVersion { + /// The version of the structure which implements this trait. After any change in the structure or its dependencies + /// which may affect the ABI, this version should be incremented. + fn struct_version() -> u64; + /// The features enabled during compilation of the structure implementing this trait. + /// Different features between the plugin and the host may cause ABI incompatibility even if the structure version is the same. + /// Use `concat_enabled_features!` to generate this string + fn struct_features() -> &'static str; +} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct PluginStructVersion { + pub version: u64, + pub name: &'static str, + pub features: &'static str, +} + +impl PluginStructVersion { + pub fn new() -> Self { + Self { + version: T::struct_version(), + name: std::any::type_name::(), + features: T::struct_features(), + } + } +} + +impl Display for PluginStructVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + " version: {}\n type: {}\n features: {}\n", + self.version, self.name, self.features + ) + } +} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Compatibility { + rust_version: Option, + vtable_version: Option, + start_args_version: Option, + instance_version: Option, + plugin_version: Option<&'static str>, + plugin_long_version: Option<&'static str>, +} + +impl Compatibility { + pub fn with_plugin_version< + StartArgsType: PluginStartArgs, + InstanceType: PluginInstance, + PluginType: Plugin, + >() -> Self { + let rust_version = Some(RustVersion::new()); + let vtable_version = Some(PluginStructVersion::new::< + PluginVTable, + >()); + let start_args_version = Some(PluginStructVersion::new::()); + let instance_version = Some(PluginStructVersion::new::()); + let plugin_version = Some(PluginType::PLUGIN_VERSION); + let plugin_long_version = Some(PluginType::PLUGIN_LONG_VERSION); + Self { + rust_version, + vtable_version, + start_args_version, + instance_version, + plugin_version, + plugin_long_version, + } + } + pub fn with_empty_plugin_version< + StartArgsType: PluginStartArgs, + InstanceType: PluginInstance, + >() -> Self { + let rust_version = Some(RustVersion::new()); + let vtable_version = Some(PluginStructVersion::new::< + PluginVTable, + >()); + let start_args_version = Some(PluginStructVersion::new::()); + let instance_version = Some(PluginStructVersion::new::()); + Self { + rust_version, + vtable_version, + start_args_version, + instance_version, + plugin_version: None, + plugin_long_version: None, + } + } + pub fn plugin_version(&self) -> Option<&'static str> { + self.plugin_version + } + pub fn plugin_long_version(&self) -> Option<&'static str> { + self.plugin_long_version + } + /// Compares fields if both are Some, otherwise skips the comparison. + /// Returns true if all the comparisons returned true, otherwise false. + /// If comparison passed or skipped, the corresponding field in both structs is set to None. + /// If comparison failed, the corresponding field in both structs is kept as is. + /// This allows not only to check compatibility, but also point to exact reasons of incompatibility. + pub fn compare(&mut self, other: &mut Self) -> bool { + let mut result = true; + Self::compare_field_fn( + &mut result, + &mut self.rust_version, + &mut other.rust_version, + RustVersion::are_compatible, + ); + Self::compare_field( + &mut result, + &mut self.vtable_version, + &mut other.vtable_version, + ); + Self::compare_field( + &mut result, + &mut self.start_args_version, + &mut other.start_args_version, + ); + Self::compare_field( + &mut result, + &mut self.instance_version, + &mut other.instance_version, + ); + // TODO: here we can later implement check for plugin version range compatibility + Self::compare_field( + &mut result, + &mut self.plugin_version, + &mut other.plugin_version, + ); + Self::compare_field( + &mut result, + &mut self.plugin_long_version, + &mut other.plugin_long_version, + ); + result + } + + // Utility function for compare single field + fn compare_field_fn bool>( + result: &mut bool, + a: &mut Option, + b: &mut Option, + compare: F, + ) { + let compatible = if let (Some(a), Some(b)) = (&a, &b) { + compare(a, b) + } else { + true + }; + if compatible { + *a = None; + *b = None; + } else { + *result = false; + } + } + fn compare_field(result: &mut bool, a: &mut Option, b: &mut Option) { + Self::compare_field_fn(result, a, b, |a, b| a == b); + } +} + +impl Display for Compatibility { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(rust_version) = &self.rust_version { + writeln!(f, "Rust version:\n{}", rust_version)?; + } + if let Some(vtable_version) = &self.vtable_version { + writeln!(f, "VTable version:\n{}", vtable_version)?; + } + if let Some(start_args_version) = &self.start_args_version { + writeln!(f, "StartArgs version:\n{}", start_args_version)?; + } + if let Some(instance_version) = &self.instance_version { + writeln!(f, "Instance version:\n{}", instance_version)?; + } + if let Some(plugin_version) = &self.plugin_version { + writeln!(f, "Plugin version: {}", plugin_version)?; + } + Ok(()) + } +} + +#[repr(C)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct RustVersion { + major: u64, + minor: u64, + patch: u64, + stable: bool, + commit: &'static str, +} + +impl Display for RustVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Rust {}.{}.{}{} commit {}", + self.major, + self.minor, + self.patch, + if self.stable { "" } else { "-nightly" }, + self.commit + ) + } +} + +const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); +impl RustVersion { + pub fn new() -> Self { + let (release, commit) = RELEASE_AND_COMMIT; + let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') { + (&release[..p], false) + } else { + (release, true) + }; + let mut split = release.split('.').map(|s| s.trim()); + RustVersion { + major: split.next().unwrap().parse().unwrap(), + minor: split.next().unwrap().parse().unwrap(), + patch: split.next().unwrap().parse().unwrap(), + stable, + commit, + } + } + pub fn are_compatible(a: &Self, b: &Self) -> bool { + if a.stable && b.stable { + a.major == b.major && a.minor == b.minor && a.patch == b.patch + } else { + a == b + } + } +} + +impl Default for RustVersion { + fn default() -> Self { + Self::new() + } +} diff --git a/plugins/zenoh-plugin-trait/src/lib.rs b/plugins/zenoh-plugin-trait/src/lib.rs index 489eb869de..6d9ac35fe9 100644 --- a/plugins/zenoh-plugin-trait/src/lib.rs +++ b/plugins/zenoh-plugin-trait/src/lib.rs @@ -33,16 +33,18 @@ //! //! Dynamic pluign is a shared library which exports set of C-repr (unmangled) functions which allows to check plugin compatibility and create plugin instance. These functiuons are defined automatically by [`declare_plugin`](crate::declare_plugin) macro. //! +mod compatibility; mod manager; mod plugin; mod vtable; +pub use compatibility::{Compatibility, PluginStructVersion, StructVersion}; pub use manager::{DeclaredPlugin, LoadedPlugin, PluginsManager, StartedPlugin}; pub use plugin::{ Plugin, PluginConditionSetter, PluginControl, PluginInstance, PluginReport, PluginStartArgs, - PluginState, PluginStatus, PluginStatusRec, PluginStructVersion, + PluginState, PluginStatus, PluginStatusRec, }; -pub use vtable::{Compatibility, PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; +pub use vtable::{PluginLoaderVersion, PluginVTable, PLUGIN_LOADER_VERSION}; use zenoh_util::concat_enabled_features; pub const FEATURES: &str = diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 438f57fb96..2ebe520f5e 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use crate::StructVersion; use serde::{Deserialize, Serialize}; use std::{borrow::Cow, ops::BitOrAssign}; use zenoh_keyexpr::keyexpr; @@ -152,19 +153,9 @@ pub trait PluginControl { } } -pub trait PluginStructVersion { - /// The version of the structure implementing this trait. After any change in the structure or its dependencies - /// which may affect the ABI, this version should be incremented. - fn struct_version() -> u64; - /// The features enabled during compilation of the structure implementing this trait. - /// Different features between the plugin and the host may cause ABI incompatibility even if the structure version is the same. - /// Use `concat_enabled_features!` to generate this string - fn struct_features() -> &'static str; -} - -pub trait PluginStartArgs: PluginStructVersion {} +pub trait PluginStartArgs: StructVersion {} -pub trait PluginInstance: PluginStructVersion + PluginControl + Send {} +pub trait PluginInstance: StructVersion + PluginControl + Send {} /// Base plugin trait. The loaded plugin pub trait Plugin: Sized + 'static { diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index a62fe7df09..664d65f31e 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -11,10 +11,10 @@ // Contributors: // ZettaScale Zenoh Team, // -use crate::*; -use std::fmt::Display; use zenoh_result::ZResult; +use crate::{Plugin, StructVersion, FEATURES}; + pub type PluginLoaderVersion = u64; pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1; @@ -26,246 +26,15 @@ pub struct PluginVTable { pub plugin_long_version: &'static str, pub start: StartFn, } -impl PluginStructVersion for PluginVTable { +impl StructVersion for PluginVTable { fn struct_version() -> u64 { - 2 + 1 } fn struct_features() -> &'static str { FEATURES } } -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct StructVersion { - pub version: u64, - pub name: &'static str, - pub features: &'static str, -} - -impl StructVersion { - pub fn new() -> Self { - Self { - version: T::struct_version(), - name: std::any::type_name::(), - features: T::struct_features(), - } - } -} - -impl Display for StructVersion { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - " version: {}\n type: {}\n features: {}\n", - self.version, self.name, self.features - ) - } -} - -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Compatibility { - rust_version: Option, - vtable_version: Option, - start_args_version: Option, - instance_version: Option, - plugin_version: Option<&'static str>, - plugin_long_version: Option<&'static str>, -} - -impl Compatibility { - pub fn with_plugin_version< - StartArgsType: PluginStartArgs, - InstanceType: PluginInstance, - PluginType: Plugin, - >() -> Self { - let rust_version = Some(RustVersion::new()); - let vtable_version = Some(StructVersion::new::< - PluginVTable, - >()); - let start_args_version = Some(StructVersion::new::()); - let instance_version = Some(StructVersion::new::()); - let plugin_version = Some(PluginType::PLUGIN_VERSION); - let plugin_long_version = Some(PluginType::PLUGIN_LONG_VERSION); - Self { - rust_version, - vtable_version, - start_args_version, - instance_version, - plugin_version, - plugin_long_version, - } - } - pub fn with_empty_plugin_version< - StartArgsType: PluginStartArgs, - InstanceType: PluginInstance, - >() -> Self { - let rust_version = Some(RustVersion::new()); - let vtable_version = Some(StructVersion::new::< - PluginVTable, - >()); - let start_args_version = Some(StructVersion::new::()); - let instance_version = Some(StructVersion::new::()); - Self { - rust_version, - vtable_version, - start_args_version, - instance_version, - plugin_version: None, - plugin_long_version: None, - } - } - pub fn plugin_version(&self) -> Option<&'static str> { - self.plugin_version - } - pub fn plugin_long_version(&self) -> Option<&'static str> { - self.plugin_long_version - } - /// Compares fields if both are Some, otherwise skips the comparison. - /// Returns true if all the comparisons returned true, otherwise false. - /// If comparison passed or skipped, the corresponding field in both structs is set to None. - /// If comparison failed, the corresponding field in both structs is kept as is. - /// This allows not only to check compatibility, but also point to exact reasons of incompatibility. - pub fn compare(&mut self, other: &mut Self) -> bool { - let mut result = true; - Self::compare_field_fn( - &mut result, - &mut self.rust_version, - &mut other.rust_version, - RustVersion::are_compatible, - ); - Self::compare_field( - &mut result, - &mut self.vtable_version, - &mut other.vtable_version, - ); - Self::compare_field( - &mut result, - &mut self.start_args_version, - &mut other.start_args_version, - ); - Self::compare_field( - &mut result, - &mut self.instance_version, - &mut other.instance_version, - ); - // TODO: here we can later implement check for plugin version range compatibility - Self::compare_field( - &mut result, - &mut self.plugin_version, - &mut other.plugin_version, - ); - Self::compare_field( - &mut result, - &mut self.plugin_long_version, - &mut other.plugin_long_version, - ); - result - } - - // Utility function for compare single field - fn compare_field_fn bool>( - result: &mut bool, - a: &mut Option, - b: &mut Option, - compare: F, - ) { - let compatible = if let (Some(a), Some(b)) = (&a, &b) { - compare(a, b) - } else { - true - }; - if compatible { - *a = None; - *b = None; - } else { - *result = false; - } - } - fn compare_field(result: &mut bool, a: &mut Option, b: &mut Option) { - Self::compare_field_fn(result, a, b, |a, b| a == b); - } -} - -impl Display for Compatibility { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(rust_version) = &self.rust_version { - writeln!(f, "Rust version:\n{}", rust_version)?; - } - if let Some(vtable_version) = &self.vtable_version { - writeln!(f, "VTable version:\n{}", vtable_version)?; - } - if let Some(start_args_version) = &self.start_args_version { - writeln!(f, "StartArgs version:\n{}", start_args_version)?; - } - if let Some(instance_version) = &self.instance_version { - writeln!(f, "Instance version:\n{}", instance_version)?; - } - if let Some(plugin_version) = &self.plugin_version { - writeln!(f, "Plugin version: {}", plugin_version)?; - } - Ok(()) - } -} - -#[repr(C)] -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct RustVersion { - major: u64, - minor: u64, - patch: u64, - stable: bool, - commit: &'static str, -} - -impl Display for RustVersion { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Rust {}.{}.{}{} commit {}", - self.major, - self.minor, - self.patch, - if self.stable { "" } else { "-nightly" }, - self.commit - ) - } -} - -const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!(); -impl RustVersion { - pub fn new() -> Self { - let (release, commit) = RELEASE_AND_COMMIT; - let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') { - (&release[..p], false) - } else { - (release, true) - }; - let mut split = release.split('.').map(|s| s.trim()); - RustVersion { - major: split.next().unwrap().parse().unwrap(), - minor: split.next().unwrap().parse().unwrap(), - patch: split.next().unwrap().parse().unwrap(), - stable, - commit, - } - } - pub fn are_compatible(a: &Self, b: &Self) -> bool { - if a.stable && b.stable { - a.major == b.major && a.minor == b.minor && a.patch == b.patch - } else { - a == b - } - } -} - -impl Default for RustVersion { - fn default() -> Self { - Self::new() - } -} - impl PluginVTable { pub fn new>() -> Self { Self { diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index d8b25c2c6d..629662e22a 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -683,7 +683,7 @@ fn plugins_status(context: &AdminContext, query: Query) { for plugin in guard.started_plugins() { with_extended_string(&mut root_key, &[plugin.name()], |plugin_key| { - // TODO: reqponse to "__version__" also, this need noot to be implemented by each plugin + // TODO: response to "__version__", this need not to be implemented by each plugin with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { if let Ok(key_expr) = KeyExpr::try_from(plugin_path_key.clone()) { if query.key_expr().intersects(&key_expr) { diff --git a/zenoh/src/net/runtime/mod.rs b/zenoh/src/net/runtime/mod.rs index 96e28f89a3..8eb57699b8 100644 --- a/zenoh/src/net/runtime/mod.rs +++ b/zenoh/src/net/runtime/mod.rs @@ -37,7 +37,7 @@ use stop_token::future::FutureExt; use stop_token::{StopSource, TimedOutError}; use uhlc::{HLCBuilder, HLC}; use zenoh_link::{EndPoint, Link}; -use zenoh_plugin_trait::{PluginStartArgs, PluginStructVersion}; +use zenoh_plugin_trait::{PluginStartArgs, StructVersion}; use zenoh_protocol::core::{whatami::WhatAmIMatcher, Locator, WhatAmI, ZenohId}; use zenoh_protocol::network::{NetworkBody, NetworkMessage}; use zenoh_result::{bail, ZResult}; @@ -66,7 +66,7 @@ pub struct Runtime { state: Arc, } -impl PluginStructVersion for Runtime { +impl StructVersion for Runtime { fn struct_version() -> u64 { 1 } diff --git a/zenoh/src/plugins/sealed.rs b/zenoh/src/plugins/sealed.rs index 9ff0311e7d..28c66d83b6 100644 --- a/zenoh/src/plugins/sealed.rs +++ b/zenoh/src/plugins/sealed.rs @@ -18,7 +18,7 @@ use crate::{prelude::Selector, runtime::Runtime}; use zenoh_core::zconfigurable; use zenoh_plugin_trait::{ - Plugin, PluginControl, PluginInstance, PluginReport, PluginStatusRec, PluginStructVersion, + Plugin, PluginControl, PluginInstance, PluginReport, PluginStatusRec, StructVersion, }; use zenoh_protocol::core::key_expr::keyexpr; use zenoh_result::ZResult; @@ -32,7 +32,7 @@ pub type RunningPlugin = Box; /// Zenoh plugins should implement this trait to ensure type-safety, even if the starting arguments and expected plugin types change in a future release. pub trait ZenohPlugin: Plugin {} -impl PluginStructVersion for RunningPlugin { +impl StructVersion for RunningPlugin { fn struct_version() -> u64 { 1 } From 279b3a862f628f7679edb0470e1c7557aeab54e7 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 18 Jan 2024 15:31:26 +0100 Subject: [PATCH 102/106] comments to declare_plugin --- plugins/zenoh-plugin-trait/src/vtable.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/zenoh-plugin-trait/src/vtable.rs b/plugins/zenoh-plugin-trait/src/vtable.rs index 664d65f31e..e1108f87f1 100644 --- a/plugins/zenoh-plugin-trait/src/vtable.rs +++ b/plugins/zenoh-plugin-trait/src/vtable.rs @@ -45,8 +45,19 @@ impl PluginVTable { } } -/// This macro will add a non-mangled functions which provides plugin version and loads it into the host. +/// This macro adds non-mangled functions which provides plugin version and loads it into the host. /// If plugin library should work also as static, consider calling this macro under feature condition +/// +/// The funcitons declared by this macro are: +/// +/// - `get_plugin_loader_version` - returns `PLUGIN_LOADER_VERSION` const of the crate. The [`PluginsManager`](crate::manager::PluginsManager) +/// will check if this version is compatible with the host. +/// - `get_compatibility` - returns [`Compatibility`](crate::Compatibility) struct which contains all version information (Rust compiler version, features used, version of plugin's structures). +/// The layout of this structure is guaranteed to be stable until the [`PLUGIN_LOADER_VERSION`](crate::PLUGIN_LOADER_VERSION) is changed, +/// so it's safe to use it in the host after call to `get_plugin_loader_version` returns compatible version. +/// Then the [`PluginsManager`](crate::manager::PluginsManager) compares the returned [`Compatibility`](crate::Compatibility) with it's own and decides if it can continue loading the plugin. +/// - `load_plugin` - returns [`PluginVTable`](crate::PluginVTable) which is able to create plugin's instance. +/// #[macro_export] macro_rules! declare_plugin { ($ty: path) => { From ff0ab93927d1d7c962ccbaa2ac44560d023b5008 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 23 Jan 2024 15:49:51 +0100 Subject: [PATCH 103/106] renamings, removed unnecessary sample configs --- plugin_test_config.json5 | 130 ------------------ plugins/zenoh-backend-example/config.json5 | 1 - plugins/zenoh-backend-example/src/lib.rs | 11 +- .../zenoh-plugin-storage-manager/src/lib.rs | 2 +- .../zenoh-plugin-trait/src/compatibility.rs | 6 +- plugins/zenoh-plugin-trait/src/manager.rs | 34 ++--- plugins/zenoh-plugin-trait/src/plugin.rs | 12 +- zenoh/src/net/runtime/adminspace.rs | 6 +- zenohd/src/main.rs | 2 +- 9 files changed, 36 insertions(+), 168 deletions(-) delete mode 100644 plugin_test_config.json5 delete mode 100644 plugins/zenoh-backend-example/config.json5 diff --git a/plugin_test_config.json5 b/plugin_test_config.json5 deleted file mode 100644 index d6c430cc3e..0000000000 --- a/plugin_test_config.json5 +++ /dev/null @@ -1,130 +0,0 @@ -// Config for testing all available plugins -// -// To run it do these steps: -// -// 1. Clone these repositories: -// ``` -// git clone https://github.com/eclipse-zenoh/zenoh.git -// git clone https://github.com/eclipse-zenoh/zenoh-backend-influxdb.git -// git clone https://github.com/eclipse-zenoh/zenoh-backend-rocksdb.git -// git clone https://github.com/eclipse-zenoh/zenoh-backend-filesystem.git -// git clone https://github.com/eclipse-zenoh/zenoh-plugin-webserver.git -// git clone https://github.com/eclipse-zenoh/zenoh-plugin-mqtt.git -// git clone https://github.com/eclipse-zenoh/zenoh-plugin-dds.git -// git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros1.git -// git clone https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds.git -// ``` -// -// 1.1. Init submodules for zenoh-plugin-ros1 -// ``` -// cd zenoh-plugin-ros1 -// git submodule init -// git submodule update -// ``` -// -// 2. Build projects -// ``` -// cd zenoh && cargo build && cd .. -// cd zenoh-backend-influxdb && cargo build && cd .. -// ... -// ``` -// -// 3. Run the zenohd server with this config file. -// -// Explicit setting RUST_LOG=info is important: without it the logs are printed by zenohd itsellf, but not by plugins. -// ``` -// cd zenoh -// RUST_LOG=info cargo run -- --config plugin_test_config.json5 -// ``` -// -// Some errors on plugin initalisation are expected due to some mandtatory properties missing in the config file, like for "influxdb" and "influxdb2" volumes. -// Though there supposedly should not be plugin loading errors due to not found files or version incompatibility -// -// -// 4. Test access plugin status through admin space -// -// The plugins information is available by "@/router/{router_id}/plugins/**". Each plugin provides by this key the json object with its status. -// Subplugins are also available by this key, e.g. "@/router/{router_id}/plugins/storage_manager/influxdb". -// ``` -// cargo run --example z_get -- -s "@/router/*/plugins/**" -// ``` -// result is -// ``` -// Received ('@/router/b04a929103101296abec19ea6cddd034/plugins/example': '{"long_version":"v0.11.0-dev-182-g48060b9c","name":"example","path":"/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_example.dylib","report":{"level":"Normal"},"state":"Started","version":"0.11.0-dev"}') -/// Received ('@/router/b04a929103101296abec19ea6cddd034/plugins/storage_manager': '{"long_version":"v0.11.0-dev-182-g48060b9c","name":"storage_manager","path":"/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_storage_manager.dylib","report":{"level":"Normal"},"state":"Started","version":"0.11.0-dev"}') -/// Received ('@/router/b04a929103101296abec19ea6cddd034/plugins/storage_manager/memory': '{"long_version":"v0.11.0-dev-182-g48060b9c","name":"storage_manager/memory","path":"","report":{"level":"Normal"},"state":"Started","version":"0.11.0-dev"}') -// ... -// ``` -// -// There is also plugin information by path "@/router/*/status/plugins/**". Later these paths should be combined -// ``` -// cargo run --example z_get -- -s "@/router/*/status/plugins/**" -// ``` -// result is -// ``` -// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/example/__path__': '/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_example.dylib') -// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/__path__': '/Users/milyin/ZS2/zenoh/target/debug/libzenoh_plugin_storage_manager.dylib') -// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/volumes/memory/__path__': '""') -// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/volumes/memory': '{"__required__":false}') -// >> Received ('@/router/b04a929103101296abec19ea6cddd034/status/plugins/storage_manager/storages/memory': '{"key_expr":"demo/memory/**","volume":"memory"}') -// ``` -// -{ - "plugins_search_dirs": [ - "target/debug", - "../zenoh-plugin-webserver/target/debug", - "../zenoh-plugin-mqtt/target/debug", - "../zenoh-plugin-dds/target/debug", - "../zenoh-plugin-ros1/target/debug", - "../zenoh-plugin-ros2dds/target/debug" - ], - - "plugins": { - // mqtt plugin, see "../zenoh-plugin-mqtt" - "mqtt": {}, - // dds plugin, see "../zenoh-plugin-dds" - "dds": {}, - // ros1 plugin, see "../zenoh-plugin-ros1" - "ros1": {}, - // ros2dds plugin, see "../zenoh-plugin-ros2dds" - "ros2dds": {}, - // example plugin, see "plugins/zenog-plugin-example" - "example": {}, - // rest plugin, see "plugins/zenoh-plugin-rest" - "rest": { - "http_port": 8080, - }, - // storage mangaer plugin, see "plugins/zenoh-plugin-storage-manager" - // supports different backends implemented as plugins also - "storage_manager": { - backend_search_dirs: [ - "target/debug", - "../zenoh-backend-influxdb/target/debug", - "../zenoh-backend-rocksdb/target/debug", - "../zenoh-backend-filesystem/target/debug" - ], - "volumes": { - // example backend, see "plugins/zenoh-backend-example" - "example": {}, - // influxdb backend from "../zenoh-backend-influxdb/v1" - "influxdb": {}, - // influxdb backend from "../zenoh-backend-influxdb/v2" - "influxdb2": {}, - // rocksdb backend, see "plugins/zenoh-backend-rocksdb" - "rocksdb": {}, - // filesystem backend, see "plugins/zenoh-backend-filesystem" - "fs": {} - }, - "storages": { - "memory": { - "volume": "memory", - "key_expr": "demo/memory/**" - }, - "example": { - "volume": "example", - "key_expr": "demo/example/**" - }, - } - }, - } -} diff --git a/plugins/zenoh-backend-example/config.json5 b/plugins/zenoh-backend-example/config.json5 deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/plugins/zenoh-backend-example/config.json5 +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/plugins/zenoh-backend-example/src/lib.rs b/plugins/zenoh-backend-example/src/lib.rs index 36586e51f0..602d29f375 100644 --- a/plugins/zenoh-backend-example/src/lib.rs +++ b/plugins/zenoh-backend-example/src/lib.rs @@ -1,9 +1,3 @@ -use std::{ - collections::{hash_map::Entry, HashMap}, - sync::Arc, -}; - -use async_std::sync::RwLock; // // Copyright (c) 2023 ZettaScale Technology // @@ -17,7 +11,12 @@ use async_std::sync::RwLock; // Contributors: // ZettaScale Zenoh Team, // +use async_std::sync::RwLock; use async_trait::async_trait; +use std::{ + collections::{hash_map::Entry, HashMap}, + sync::Arc, +}; use zenoh::{prelude::OwnedKeyExpr, sample::Sample, time::Timestamp, value::Value}; use zenoh_backend_traits::{ config::{StorageConfig, VolumeConfig}, diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index b1f1e15da7..eed1cc8a9d 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -316,7 +316,7 @@ impl RunningPluginTrait for StorageRuntime { }); let guard = self.0.lock().unwrap(); with_extended_string(&mut key, &["/volumes/"], |key| { - for plugin in guard.plugins_manager.started_plugins() { + for plugin in guard.plugins_manager.started_plugins_iter() { with_extended_string(key, &[plugin.name()], |key| { with_extended_string(key, &["/__path__"], |key| { if keyexpr::new(key.as_str()) diff --git a/plugins/zenoh-plugin-trait/src/compatibility.rs b/plugins/zenoh-plugin-trait/src/compatibility.rs index 2887270a85..7b52bc5fbf 100644 --- a/plugins/zenoh-plugin-trait/src/compatibility.rs +++ b/plugins/zenoh-plugin-trait/src/compatibility.rs @@ -203,9 +203,9 @@ impl Display for Compatibility { #[repr(C)] #[derive(Debug, PartialEq, Eq, Clone)] pub struct RustVersion { - major: u64, - minor: u64, - patch: u64, + major: u32, + minor: u32, + patch: u32, stable: bool, commit: &'static str, } diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index 48988dfe22..940d389789 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -175,7 +175,7 @@ impl } /// Lists all plugins - pub fn declared_plugins( + pub fn declared_plugins_iter( &self, ) -> impl Iterator> + '_ { self.plugins @@ -184,7 +184,7 @@ impl } /// Lists all plugins mutable - pub fn declared_plugins_mut( + pub fn declared_plugins_iter_mut( &mut self, ) -> impl Iterator> + '_ { self.plugins @@ -193,41 +193,41 @@ impl } /// Lists the loaded plugins - pub fn loaded_plugins( + pub fn loaded_plugins_iter( &self, ) -> impl Iterator> + '_ { - self.declared_plugins().filter_map(|p| p.loaded()) + self.declared_plugins_iter().filter_map(|p| p.loaded()) } /// Lists the loaded plugins mutable - pub fn loaded_plugins_mut( + pub fn loaded_plugins_iter_mut( &mut self, ) -> impl Iterator> + '_ { // self.plugins_mut().filter_map(|p| p.loaded_mut()) - self.declared_plugins_mut().filter_map(|p| p.loaded_mut()) + self.declared_plugins_iter_mut().filter_map(|p| p.loaded_mut()) } /// Lists the started plugins - pub fn started_plugins( + pub fn started_plugins_iter( &self, ) -> impl Iterator> + '_ { - self.loaded_plugins().filter_map(|p| p.started()) + self.loaded_plugins_iter().filter_map(|p| p.started()) } /// Lists the started plugins mutable - pub fn started_plugins_mut( + pub fn started_plugins_iter_mut( &mut self, ) -> impl Iterator> + '_ { - self.loaded_plugins_mut().filter_map(|p| p.started_mut()) + self.loaded_plugins_iter_mut().filter_map(|p| p.started_mut()) } - /// Returns single plugin record + /// Returns single plugin record by name pub fn plugin(&self, name: &str) -> Option<&dyn DeclaredPlugin> { let index = self.get_plugin_index(name)?; Some(&self.plugins[index]) } - /// Returns mutable plugin record + /// Returns mutable plugin record by name pub fn plugin_mut( &mut self, name: &str, @@ -236,12 +236,12 @@ impl Some(&mut self.plugins[index]) } - /// Returns loaded plugin record + /// Returns loaded plugin record by name pub fn loaded_plugin(&self, name: &str) -> Option<&dyn LoadedPlugin> { self.plugin(name)?.loaded() } - /// Returns mutable loaded plugin record + /// Returns mutable loaded plugin record by name pub fn loaded_plugin_mut( &mut self, name: &str, @@ -249,12 +249,12 @@ impl self.plugin_mut(name)?.loaded_mut() } - /// Returns started plugin record + /// Returns started plugin record by name pub fn started_plugin(&self, name: &str) -> Option<&dyn StartedPlugin> { self.loaded_plugin(name)?.started() } - /// Returns mutable started plugin record + /// Returns mutable started plugin record by name pub fn started_plugin_mut( &mut self, name: &str, @@ -273,7 +273,7 @@ impl P names ); let mut plugins = Vec::new(); - for plugin in self.declared_plugins() { + for plugin in self.declared_plugins_iter() { let name = unsafe { keyexpr::from_str_unchecked(plugin.name()) }; if names.includes(name) { let status = PluginStatusRec::new(plugin.as_status()); diff --git a/plugins/zenoh-plugin-trait/src/plugin.rs b/plugins/zenoh-plugin-trait/src/plugin.rs index 2ebe520f5e..f1c2d09385 100644 --- a/plugins/zenoh-plugin-trait/src/plugin.rs +++ b/plugins/zenoh-plugin-trait/src/plugin.rs @@ -35,7 +35,7 @@ pub enum PluginState { #[derive(Copy, Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, PartialOrd, Ord)] pub enum PluginReportLevel { #[default] - Normal, + Info, Warning, Error, } @@ -203,8 +203,8 @@ impl PluginReport { self.level |= PluginReportLevel::Warning; self.messages.push(warning.into()); } - pub fn add_message>>(&mut self, message: S) { - self.level |= PluginReportLevel::Normal; + pub fn add_info>>(&mut self, message: S) { + self.level |= PluginReportLevel::Info; self.messages.push(message.into()); } pub fn messages(&self) -> &[Cow<'static, str>] { @@ -215,7 +215,7 @@ impl PluginReport { pub trait PluginConditionSetter { fn add_error(self, report: &mut PluginReport) -> Self; fn add_warning(self, report: &mut PluginReport) -> Self; - fn add_message(self, report: &mut PluginReport) -> Self; + fn add_info(self, report: &mut PluginReport) -> Self; } impl PluginConditionSetter for core::result::Result { @@ -231,9 +231,9 @@ impl PluginConditionSetter for core::result::Result { } self } - fn add_message(self, report: &mut PluginReport) -> Self { + fn add_info(self, report: &mut PluginReport) -> Self { if let Err(e) = &self { - report.add_message(e.to_string()); + report.add_info(e.to_string()); } self } diff --git a/zenoh/src/net/runtime/adminspace.rs b/zenoh/src/net/runtime/adminspace.rs index 629662e22a..b109774054 100644 --- a/zenoh/src/net/runtime/adminspace.rs +++ b/zenoh/src/net/runtime/adminspace.rs @@ -171,7 +171,7 @@ impl AdminSpace { ); let mut active_plugins = plugins_mgr - .started_plugins() + .started_plugins_iter() .map(|rec| (rec.name().to_string(), rec.path().to_string())) .collect::>(); @@ -458,7 +458,7 @@ fn router_data(context: &AdminContext, query: Query) { let plugins: serde_json::Value = { let plugins_mgr = zlock!(context.plugins_mgr); plugins_mgr - .started_plugins() + .started_plugins_iter() .map(|rec| (rec.name(), json!({ "path": rec.path() }))) .collect() }; @@ -681,7 +681,7 @@ fn plugins_status(context: &AdminContext, query: Query) { let guard = zlock!(context.plugins_mgr); let mut root_key = format!("@/router/{}/status/plugins/", &context.zid_str); - for plugin in guard.started_plugins() { + for plugin in guard.started_plugins_iter() { with_extended_string(&mut root_key, &[plugin.name()], |plugin_key| { // TODO: response to "__version__", this need not to be implemented by each plugin with_extended_string(plugin_key, &["/__path__"], |plugin_path_key| { diff --git a/zenohd/src/main.rs b/zenohd/src/main.rs index c6ea00a9d4..b0d29ea89b 100644 --- a/zenohd/src/main.rs +++ b/zenohd/src/main.rs @@ -154,7 +154,7 @@ fn main() { } }; - for plugin in plugin_mgr.loaded_plugins_mut() { + for plugin in plugin_mgr.loaded_plugins_iter_mut() { let required = required_plugins.contains(plugin.name()); log::info!( "Starting {req} plugin \"{name}\"", From 98277b07ac0c2abd34cee5c22430d188134f4005 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 23 Jan 2024 15:50:47 +0100 Subject: [PATCH 104/106] cargo fmt --- plugins/zenoh-plugin-trait/src/manager.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/zenoh-plugin-trait/src/manager.rs b/plugins/zenoh-plugin-trait/src/manager.rs index 940d389789..d975fa0e25 100644 --- a/plugins/zenoh-plugin-trait/src/manager.rs +++ b/plugins/zenoh-plugin-trait/src/manager.rs @@ -204,7 +204,8 @@ impl &mut self, ) -> impl Iterator> + '_ { // self.plugins_mut().filter_map(|p| p.loaded_mut()) - self.declared_plugins_iter_mut().filter_map(|p| p.loaded_mut()) + self.declared_plugins_iter_mut() + .filter_map(|p| p.loaded_mut()) } /// Lists the started plugins @@ -218,7 +219,8 @@ impl pub fn started_plugins_iter_mut( &mut self, ) -> impl Iterator> + '_ { - self.loaded_plugins_iter_mut().filter_map(|p| p.started_mut()) + self.loaded_plugins_iter_mut() + .filter_map(|p| p.started_mut()) } /// Returns single plugin record by name From 581f765ca61ac323808b01f851888d8038eec0bb Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 23 Jan 2024 16:23:27 +0100 Subject: [PATCH 105/106] debug code removed --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index eed1cc8a9d..977d0497a1 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -287,10 +287,7 @@ impl RunningPluginTrait for StorageRuntime { let name = { zlock!(self.0).name.clone() }; let old = PluginConfig::try_from((&name, old))?; let new = PluginConfig::try_from((&name, new))?; - log::info!("old: {:?}", &old); - log::info!("new: {:?}", &new); let diffs = ConfigDiff::diffs(old, new); - log::info!("diff: {:?}", &diffs); { zlock!(self.0).update(diffs) }?; Ok(None) } From 0cc130ae7b8af624b4a925063e07317e0885f0ff Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 23 Jan 2024 16:35:00 +0100 Subject: [PATCH 106/106] log::info changed to log::debug --- plugins/zenoh-plugin-storage-manager/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/zenoh-plugin-storage-manager/src/lib.rs b/plugins/zenoh-plugin-storage-manager/src/lib.rs index 977d0497a1..0db30bbd6a 100644 --- a/plugins/zenoh-plugin-storage-manager/src/lib.rs +++ b/plugins/zenoh-plugin-storage-manager/src/lib.rs @@ -287,8 +287,13 @@ impl RunningPluginTrait for StorageRuntime { let name = { zlock!(self.0).name.clone() }; let old = PluginConfig::try_from((&name, old))?; let new = PluginConfig::try_from((&name, new))?; + log::debug!("config change requested for plugin '{}'", name); + log::debug!("old config: {:?}", &old); + log::debug!("new config: {:?}", &new); let diffs = ConfigDiff::diffs(old, new); + log::debug!("applying diff: {:?}", &diffs); { zlock!(self.0).update(diffs) }?; + log::debug!("applying diff done"); Ok(None) }