Skip to content

Commit

Permalink
Allow using FabricClient in non-tokio projects and refactor interface. (
Browse files Browse the repository at this point in the history
#122)

While you still end up needing to drop back down to the com level at
least today, not having to write casts by hand is nice.

Also, it's unnecessary to clone the COM level interface all the time.
Make FabricClient own the high level wrappers; if you need it to live
longer, you can clone it. This is a breaking change, so may warrant a
version bump.
  • Loading branch information
cgettys-microsoft authored Jan 10, 2025
1 parent 3b001c6 commit 2e797d0
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 29 deletions.
4 changes: 4 additions & 0 deletions crates/libs/core/src/client/health_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ pub struct HealthClient {

// Public implementation block
impl HealthClient {
pub fn get_com(&self) -> IFabricHealthClient4 {
self.com.clone()
}

pub fn from_com(com: IFabricHealthClient4) -> Self {
Self { com: com.clone() }
}
Expand Down
53 changes: 29 additions & 24 deletions crates/libs/core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@ impl FabricClientBuilder {
// https://github.com/microsoft/service-fabric/blob/master/src/prod/src/managed/Api/src/System/Fabric/FabricClient.cs
#[derive(Debug, Clone)]
pub struct FabricClient {
com_property_client: IFabricPropertyManagementClient2,
com_service_client: IFabricServiceManagementClient6,
com_query_client: IFabricQueryClient10,
com_health_client: IFabricHealthClient4,
property_client: PropertyManagementClient,
service_client: ServiceManagementClient,
query_client: QueryClient,
health_client: HealthClient,
}

impl FabricClient {
Expand All @@ -214,11 +214,6 @@ impl FabricClient {
FabricClientBuilder::new()
}

/// Get a copy of COM object
pub fn get_com(&self) -> IFabricPropertyManagementClient2 {
self.com_property_client.clone()
}

/// Creates from com directly. This gives the user freedom to create com from
/// custom code and pass it in.
/// For the final state of FabricClient, this function should be private.
Expand All @@ -231,36 +226,46 @@ impl FabricClient {
let com_query_client = com.clone().cast::<IFabricQueryClient10>().unwrap();
let com_health_client = com.clone().cast::<IFabricHealthClient4>().unwrap();
Self {
com_property_client,
com_service_client,
com_query_client,
com_health_client,
property_client: PropertyManagementClient::from_com(com_property_client),
service_client: ServiceManagementClient::from_com(com_service_client),
query_client: QueryClient::from_com(com_query_client),
health_client: HealthClient::from_com(com_health_client),
}
}

/// Get the client for managing Fabric Properties in Naming Service
pub fn get_property_manager(&self) -> PropertyManagementClient {
PropertyManagementClient {
_com: self.com_property_client.clone(),
}
pub fn get_property_manager(&self) -> &PropertyManagementClient {
&self.property_client
}

/// Get the client for quering Service Fabric information.
pub fn get_query_manager(&self) -> QueryClient {
QueryClient::from_com(self.com_query_client.clone())
pub fn get_query_manager(&self) -> &QueryClient {
&self.query_client
}

/// Get the client for managing service information and lifecycles.
pub fn get_service_manager(&self) -> ServiceManagementClient {
ServiceManagementClient::from_com(self.com_service_client.clone())
pub fn get_service_manager(&self) -> &ServiceManagementClient {
&self.service_client
}

/// Get the client for get/set Service Fabric health properties.
pub fn get_health_manager(&self) -> HealthClient {
HealthClient::from_com(self.com_health_client.clone())
pub fn get_health_manager(&self) -> &HealthClient {
&self.health_client
}
}

#[derive(Debug, Clone)]
pub struct PropertyManagementClient {
_com: IFabricPropertyManagementClient2,
com: IFabricPropertyManagementClient2,
}

impl PropertyManagementClient {
/// Get a copy of COM object
pub fn get_com(&self) -> IFabricPropertyManagementClient2 {
self.com.clone()
}

fn from_com(com: IFabricPropertyManagementClient2) -> Self {
Self { com }
}
}
16 changes: 14 additions & 2 deletions crates/libs/core/src/client/query_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

#![cfg_attr(
not(feature = "tokio_async"),
allow(unused_imports) // reason = "code configured out"
)]
use std::{ffi::c_void, time::Duration};

use mssf_com::{
Expand All @@ -19,9 +22,10 @@ use mssf_com::{
},
};

#[cfg(feature = "tokio_async")]
use crate::sync::{fabric_begin_end_proxy2, CancellationToken, FabricReceiver2};
use crate::{
strings::get_pcwstr_from_opt,
sync::{fabric_begin_end_proxy2, CancellationToken, FabricReceiver2},
types::{
NodeList, NodeQueryDescription, PartitionLoadInformation,
PartitionLoadInformationQueryDescription, ServicePartitionList,
Expand All @@ -37,6 +41,7 @@ pub struct QueryClient {
// Internal implementation block
// Internal functions focuses on changing SF callback to async future,
// while the public apis impl focuses on type conversion.
#[cfg(feature = "tokio_async")]
impl QueryClient {
pub fn get_node_list_internal(
&self,
Expand Down Expand Up @@ -109,10 +114,17 @@ impl QueryClient {
}

impl QueryClient {
pub fn get_com(&self) -> IFabricQueryClient10 {
self.com.clone()
}

pub fn from_com(com: IFabricQueryClient10) -> Self {
Self { com: com.clone() }
}
}

#[cfg(feature = "tokio_async")]
impl QueryClient {
// List nodes in the cluster
pub async fn get_node_list(
&self,
Expand Down
19 changes: 17 additions & 2 deletions crates/libs/core/src/client/svc_mgmt_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

#![cfg_attr(
not(feature = "tokio_async"),
allow(unused_imports) // reason = "code configured out"
)]
use std::{ffi::c_void, time::Duration};

use mssf_com::{
Expand All @@ -22,10 +25,12 @@ use mssf_com::{
};
use windows_core::{WString, PCWSTR};

#[cfg(feature = "tokio_async")]
use crate::sync::{fabric_begin_end_proxy2, CancellationToken, FabricReceiver2};

use crate::{
iter::{FabricIter, FabricListAccessor},
strings::WStringWrap,
sync::{fabric_begin_end_proxy2, CancellationToken, FabricReceiver2},
types::{
RemoveReplicaDescription, RestartReplicaDescription, ServiceNotificationFilterDescription,
},
Expand All @@ -37,7 +42,13 @@ pub struct ServiceManagementClient {
com: IFabricServiceManagementClient6,
}

impl ServiceManagementClient {
pub fn get_com(&self) -> IFabricServiceManagementClient6 {
self.com.clone()
}
}
// internal implementation block
#[cfg(feature = "tokio_async")]
impl ServiceManagementClient {
fn resolve_service_partition_internal(
&self,
Expand Down Expand Up @@ -144,7 +155,11 @@ impl ServiceManagementClient {
pub fn from_com(com: IFabricServiceManagementClient6) -> Self {
Self { com: com.clone() }
}
}

// public implementation block - tokio required
#[cfg(feature = "tokio_async")]
impl ServiceManagementClient {
// Resolve service partition
pub async fn resolve_service_partition(
&self,
Expand Down
1 change: 0 additions & 1 deletion crates/libs/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
// SF lib entrypoint apis.
pub mod api;
pub use api::API_TABLE;
#[cfg(feature = "tokio_async")]
pub mod client;
#[cfg(feature = "config_source")]
pub mod conf;
Expand Down

0 comments on commit 2e797d0

Please sign in to comment.