diff --git a/crates/libs/core/src/runtime/activation_context.rs b/crates/libs/core/src/runtime/activation_context.rs index 7f321221..3c5dec40 100644 --- a/crates/libs/core/src/runtime/activation_context.rs +++ b/crates/libs/core/src/runtime/activation_context.rs @@ -14,7 +14,16 @@ use crate::{ Error, WString, PCWSTR, }; -use super::config::ConfigurationPackage; +use super::{ + config::ConfigurationPackage, + package_change::{ + config::{ + ConfigurationPackageChangeCallbackHandle, ConfigurationPackageChangeEventHandlerBridge, + LambdaConfigurationPackageEventHandler, + }, + ConfigurationPackageChangeEvent, + }, +}; #[derive(Debug, Clone)] pub struct CodePackageActivationContext { @@ -132,6 +141,18 @@ impl CodePackageActivationContext { pub fn get_com(&self) -> IFabricCodePackageActivationContext6 { self.com_impl.clone() } + + pub fn register_config_package_change_handler<T>( + &self, + handler: T, + ) -> crate::Result<ConfigurationPackageChangeCallbackHandle> + where + T: Fn(&ConfigurationPackageChangeEvent) -> crate::Result<()> + 'static, + { + let lambda_handler = LambdaConfigurationPackageEventHandler::new(handler); + let bridge = ConfigurationPackageChangeEventHandlerBridge::new(lambda_handler); + ConfigurationPackageChangeCallbackHandle::register(self.get_com(), bridge.into()) + } } impl From<IFabricCodePackageActivationContext6> for CodePackageActivationContext { diff --git a/crates/libs/core/src/runtime/package_change/config.rs b/crates/libs/core/src/runtime/package_change/config.rs index 432890fe..550b9a27 100644 --- a/crates/libs/core/src/runtime/package_change/config.rs +++ b/crates/libs/core/src/runtime/package_change/config.rs @@ -9,7 +9,7 @@ use mssf_com::FabricRuntime::{ IFabricConfigurationPackageChangeHandler_Impl, }; -use crate::runtime::{config::ConfigurationPackage, CodePackageActivationContext}; +use crate::runtime::config::ConfigurationPackage; use super::ConfigurationPackageChangeEvent; @@ -85,7 +85,7 @@ where /// This is used in FabricClientBuilder to build function into handler. /// Not exposed to user. /// Strictly speaking we don't need this layer. But it would allow us to open the door to trait implementations someday -struct LambdaConfigurationPackageEventHandler<T> +pub(crate) struct LambdaConfigurationPackageEventHandler<T> where T: Fn(&ConfigurationPackageChangeEvent) -> crate::Result<()> + 'static, { @@ -111,31 +111,31 @@ where } /// This struct ensures that the handle is retained and deregistered before the implementation is dropped -struct ConfigurationPackageChangeHandle { - activation_ctx: IFabricCodePackageActivationContext6, +pub struct ConfigurationPackageChangeCallbackHandle { + activation_context: IFabricCodePackageActivationContext6, handle: i64, } -impl ConfigurationPackageChangeHandle { - pub fn new( - activation_context: &CodePackageActivationContext, +impl ConfigurationPackageChangeCallbackHandle { + pub fn register( + activation_context: IFabricCodePackageActivationContext6, implementation: IFabricConfigurationPackageChangeHandler, ) -> crate::Result<Self> { - let activation_ctx = activation_context.get_com(); - let handle = - unsafe { activation_ctx.RegisterConfigurationPackageChangeHandler(&implementation) }?; + let handle = unsafe { + activation_context.RegisterConfigurationPackageChangeHandler(&implementation) + }?; Ok(Self { - activation_ctx, + activation_context, handle, }) } } -impl Drop for ConfigurationPackageChangeHandle { +impl Drop for ConfigurationPackageChangeCallbackHandle { fn drop(&mut self) { unsafe { - self.activation_ctx + self.activation_context .UnregisterConfigurationPackageChangeHandler(self.handle) } .unwrap(); diff --git a/crates/libs/core/src/runtime/package_change/mod.rs b/crates/libs/core/src/runtime/package_change/mod.rs index 217aac36..5d7aeaa6 100644 --- a/crates/libs/core/src/runtime/package_change/mod.rs +++ b/crates/libs/core/src/runtime/package_change/mod.rs @@ -4,7 +4,7 @@ // ------------------------------------------------------------ //! This module supports implementing callbacks when Service Fabric Packages are changed //! -pub(super) mod config; +pub mod config; /// The ways a given Service Fabric Package (e.g. ConfigurationPackage or DataPackage) can change #[derive(Debug, PartialEq, Eq, Clone)] diff --git a/crates/samples/no_default_features/src/lib.rs b/crates/samples/no_default_features/src/lib.rs index 102729c2..e27db206 100644 --- a/crates/samples/no_default_features/src/lib.rs +++ b/crates/samples/no_default_features/src/lib.rs @@ -10,27 +10,26 @@ //! //! This sample demonstrates it is possible to use the library with default-features = false and ensures that that scenario remains compiling as PRs go into the repository. //! -use std::borrow::Borrow; -use mssf_core::{client::FabricClientBuilder, runtime::CodePackageActivationContext}; +use mssf_core::runtime::{package_change::PackageChangeEvent, CodePackageActivationContext}; #[no_mangle] fn test_fn() { - // Make sure we link something - // - let my_ctx = CodePackageActivationContext::create(); - my_ctx.unwrap(); + let my_ctx = CodePackageActivationContext::create().unwrap(); // One might wish to use such a callback to e.g. trigger custom handling of configuration changes // This doesn't require the config feature to be enabled - let _client = FabricClientBuilder::new() - .with_on_configuration_package_change(|c| + let _handler = my_ctx.register_config_package_change_handler( |c| { - let change_type = c.change_type; - let changed_package_name = c.config_package.as_ref().map(|x |x.get_description().name.to_string_lossy()); - let changed_package_str = changed_package_name.borrow().as_deref().unwrap_or("Unknown package name"); + let (some_package, change_type) = match c + { + PackageChangeEvent::Addition { new_package } => (new_package, "Addition"), + PackageChangeEvent::Removal { previous_package } => (previous_package, "Removal"), + PackageChangeEvent::Modification { previous_package: _, new_package } => (new_package, "Modification"), + }; + let changed_package_name = some_package.get_description().name.to_string_lossy(); + let changed_package_str = &changed_package_name; println!("Received config package change of type {change_type:?} to package {changed_package_str}"); Ok(()) } - ) - .build(); + ).unwrap(); }