use std::{ffi::c_void, time::Duration};
use mssf_com::{
FabricClient::{
IFabricGetNodeListResult2, IFabricGetPartitionListResult2, IFabricGetReplicaListResult2,
IFabricQueryClient10,
},
FabricTypes::{
FABRIC_NODE_QUERY_DESCRIPTION, FABRIC_NODE_QUERY_DESCRIPTION_EX1,
FABRIC_NODE_QUERY_DESCRIPTION_EX2, FABRIC_NODE_QUERY_DESCRIPTION_EX3,
FABRIC_SERVICE_PARTITION_QUERY_DESCRIPTION, FABRIC_SERVICE_REPLICA_QUERY_DESCRIPTION,
},
};
use crate::{
strings::get_pcwstr_from_opt,
sync::{fabric_begin_end_proxy2, CancellationToken, FabricReceiver2},
types::{
NodeList, NodeQueryDescription, ServicePartitionList, ServicePartitionQueryDescription,
ServiceReplicaList, ServiceReplicaQueryDescription,
},
};
pub struct QueryClient {
com: IFabricQueryClient10,
}
impl QueryClient {
pub fn get_node_list_internal(
&self,
query_description: &FABRIC_NODE_QUERY_DESCRIPTION,
timeout_milliseconds: u32,
cancellation_token: Option<CancellationToken>,
) -> FabricReceiver2<::windows_core::Result<IFabricGetNodeListResult2>> {
let com1 = &self.com;
let com2 = self.com.clone();
fabric_begin_end_proxy2(
move |callback| unsafe {
com1.BeginGetNodeList(query_description, timeout_milliseconds, callback)
},
move |ctx| unsafe { com2.EndGetNodeList2(ctx) },
cancellation_token,
)
}
fn get_partition_list_internal(
&self,
desc: &FABRIC_SERVICE_PARTITION_QUERY_DESCRIPTION,
timeout_milliseconds: u32,
cancellation_token: Option<CancellationToken>,
) -> FabricReceiver2<crate::Result<IFabricGetPartitionListResult2>> {
let com1 = &self.com;
let com2 = self.com.clone();
fabric_begin_end_proxy2(
move |callback| unsafe {
com1.BeginGetPartitionList(desc, timeout_milliseconds, callback)
},
move |ctx| unsafe { com2.EndGetPartitionList2(ctx) },
cancellation_token,
)
}
fn get_replica_list_internal(
&self,
desc: &FABRIC_SERVICE_REPLICA_QUERY_DESCRIPTION,
timeout_milliseconds: u32,
cancellation_token: Option<CancellationToken>,
) -> FabricReceiver2<crate::Result<IFabricGetReplicaListResult2>> {
let com1 = &self.com;
let com2 = self.com.clone();
fabric_begin_end_proxy2(
move |callback| unsafe {
com1.BeginGetReplicaList(desc, timeout_milliseconds, callback)
},
move |ctx| unsafe { com2.EndGetReplicaList2(ctx) },
cancellation_token,
)
}
}
impl QueryClient {
pub fn from_com(com: IFabricQueryClient10) -> Self {
Self { com: com.clone() }
}
pub async fn get_node_list(
&self,
desc: &NodeQueryDescription,
timeout: Duration,
cancellation_token: Option<crate::sync::CancellationToken>,
) -> windows_core::Result<NodeList> {
let fu;
{
let ex3 = FABRIC_NODE_QUERY_DESCRIPTION_EX3 {
MaxResults: desc.paged_query.max_results.unwrap_or(0),
Reserved: std::ptr::null_mut(),
};
let ex2 = FABRIC_NODE_QUERY_DESCRIPTION_EX2 {
NodeStatusFilter: desc.node_status_filter.bits(),
Reserved: std::ptr::addr_of!(ex3) as *mut c_void,
};
let ex1 = FABRIC_NODE_QUERY_DESCRIPTION_EX1 {
ContinuationToken: get_pcwstr_from_opt(&desc.paged_query.continuation_token),
Reserved: std::ptr::addr_of!(ex2) as *mut c_void,
};
let arg = FABRIC_NODE_QUERY_DESCRIPTION {
NodeNameFilter: get_pcwstr_from_opt(&desc.node_name_filter),
Reserved: std::ptr::addr_of!(ex1) as *mut c_void,
};
fu = self.get_node_list_internal(
&arg,
timeout.as_millis().try_into().unwrap(),
cancellation_token,
);
}
let res = fu.await??;
Ok(NodeList::from_com(res))
}
pub async fn get_partition_list(
&self,
desc: &ServicePartitionQueryDescription,
timeout: Duration,
cancellation_token: Option<CancellationToken>,
) -> crate::Result<ServicePartitionList> {
let raw: FABRIC_SERVICE_PARTITION_QUERY_DESCRIPTION = desc.into();
let mili = timeout.as_millis() as u32;
let com = self
.get_partition_list_internal(&raw, mili, cancellation_token)
.await??;
Ok(ServicePartitionList::new(com))
}
pub async fn get_replica_list(
&self,
desc: &ServiceReplicaQueryDescription,
timeout: Duration,
cancellation_token: Option<CancellationToken>,
) -> crate::Result<ServiceReplicaList> {
let raw: FABRIC_SERVICE_REPLICA_QUERY_DESCRIPTION = desc.into();
let mili = timeout.as_millis() as u32;
let com = self
.get_replica_list_internal(&raw, mili, cancellation_token)
.await??;
Ok(ServiceReplicaList::new(com))
}
}