diff --git a/crates/libs/core/src/runtime/activation_context.rs b/crates/libs/core/src/runtime/activation_context.rs index e9138b8..40afb8a 100644 --- a/crates/libs/core/src/runtime/activation_context.rs +++ b/crates/libs/core/src/runtime/activation_context.rs @@ -144,6 +144,8 @@ impl CodePackageActivationContext { self.com_impl.clone() } + /// Register a configuration package change handler callback + /// Consider using [`AutoConfigurationPackageChangeCallbackHandle::new`] instead of this directly. pub fn register_configuration_package_change_handler( &self, handler: T, diff --git a/crates/libs/core/src/runtime/package_change/config.rs b/crates/libs/core/src/runtime/package_change/config.rs index 5c24a4b..66ef85e 100644 --- a/crates/libs/core/src/runtime/package_change/config.rs +++ b/crates/libs/core/src/runtime/package_change/config.rs @@ -8,7 +8,7 @@ use mssf_com::FabricRuntime::{ IFabricConfigurationPackageChangeHandler, IFabricConfigurationPackageChangeHandler_Impl, }; -use crate::runtime::config::ConfigurationPackage; +use crate::runtime::{config::ConfigurationPackage, CodePackageActivationContext}; use super::ConfigurationPackageChangeEvent; @@ -110,6 +110,8 @@ where } } +/// An opaque id representing a registered Configuration Package Change callback +#[derive(Debug)] pub struct ConfigurationPackageChangeCallbackHandle(pub(crate) i64); impl ConfigurationPackageChangeCallbackHandle { @@ -119,3 +121,38 @@ impl ConfigurationPackageChangeCallbackHandle { Self(com) } } + +/// This struct manages deregistering the Service Fabric Config Package Change callback +/// when it leaves scope. +#[derive(Debug)] +pub struct AutoConfigurationPackageChangeCallbackHandle { + /// Service Fabric Activation Context + activation_ctx: CodePackageActivationContext, + /// Handle to deregister on drop + handle: Option, +} + +impl AutoConfigurationPackageChangeCallbackHandle { + /// Register a new handle for the provided lambda. + /// Clones (e.g. adjusts reference count) on activation_ctx + pub fn new(activation_ctx: &CodePackageActivationContext, handler: T) -> crate::Result + where + T: Fn(&ConfigurationPackageChangeEvent) + 'static, + { + let handle = activation_ctx.register_configuration_package_change_handler(handler)?; + Ok(Self { + activation_ctx: activation_ctx.clone(), + handle: Some(handle), + }) + } +} + +impl Drop for AutoConfigurationPackageChangeCallbackHandle { + fn drop(&mut self) { + if let Some(my_handle) = self.handle.take() { + self.activation_ctx + .unregister_configuration_package_change_handler(my_handle) + .expect("Unregistering handle should succeed."); + } + } +}