Skip to content

Commit

Permalink
Add a AutoConfigurationPackageChangeCallbackHandle RAII Type (#121)
Browse files Browse the repository at this point in the history
Add a useful RAII type to ensure handle is unregistered when type is
dropped.

With more work, it could handle lambdas that aren't 'static too, but
leaving that for future.
  • Loading branch information
cgettys-microsoft authored Jan 10, 2025
1 parent 2e797d0 commit 2e4c285
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
2 changes: 2 additions & 0 deletions crates/libs/core/src/runtime/activation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(
&self,
handler: T,
Expand Down
39 changes: 38 additions & 1 deletion crates/libs/core/src/runtime/package_change/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand All @@ -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<ConfigurationPackageChangeCallbackHandle>,
}

impl AutoConfigurationPackageChangeCallbackHandle {
/// Register a new handle for the provided lambda.
/// Clones (e.g. adjusts reference count) on activation_ctx
pub fn new<T>(activation_ctx: &CodePackageActivationContext, handler: T) -> crate::Result<Self>
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.");
}
}
}

0 comments on commit 2e4c285

Please sign in to comment.