Skip to main content

mssf_core/client/
query_client.rs

1// ------------------------------------------------------------
2// Copyright (c) Microsoft Corporation.  All rights reserved.
3// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4// ------------------------------------------------------------
5use std::time::Duration;
6
7use mssf_com::{
8    FabricClient::{
9        IFabricGetApplicationListResult2, IFabricGetDeployedServiceReplicaDetailResult,
10        IFabricGetNodeListResult2, IFabricGetPartitionListResult2,
11        IFabricGetPartitionLoadInformationResult, IFabricGetReplicaListResult2,
12        IFabricQueryClient13,
13    },
14    FabricTypes::{
15        FABRIC_APPLICATION_QUERY_DESCRIPTION,
16        FABRIC_DEPLOYED_SERVICE_REPLICA_DETAIL_QUERY_DESCRIPTION, FABRIC_NODE_QUERY_DESCRIPTION,
17        FABRIC_PARTITION_LOAD_INFORMATION_QUERY_DESCRIPTION,
18        FABRIC_SERVICE_PARTITION_QUERY_DESCRIPTION, FABRIC_SERVICE_QUERY_DESCRIPTION,
19        FABRIC_SERVICE_REPLICA_QUERY_DESCRIPTION,
20    },
21};
22
23use crate::mem::{BoxPool, GetRawWithBoxPool};
24
25use crate::types::{
26    DeployedServiceReplicaDetailQueryDescription, DeployedServiceReplicaDetailQueryResult,
27    GetPartitionLoadInformationResult, NodeListResult, NodeQueryDescription,
28    PartitionLoadInformationQueryDescription, ServicePartitionList,
29    ServicePartitionQueryDescription, ServiceReplicaList, ServiceReplicaQueryDescription,
30};
31use crate::{
32    runtime::executor::BoxedCancelToken,
33    sync::{FabricReceiver, fabric_begin_end_proxy},
34    types::ServiceQueryDescription,
35};
36
37#[derive(Debug, Clone)]
38pub struct QueryClient {
39    com: IFabricQueryClient13,
40}
41
42// Internal implementation block
43// Internal functions focuses on changing SF callback to async future,
44// while the public apis impl focuses on type conversion.
45
46impl QueryClient {
47    pub fn get_node_list_internal(
48        &self,
49        query_description: &FABRIC_NODE_QUERY_DESCRIPTION,
50        timeout_milliseconds: u32,
51        cancellation_token: Option<BoxedCancelToken>,
52    ) -> FabricReceiver<crate::WinResult<IFabricGetNodeListResult2>> {
53        let com1 = &self.com;
54        let com2 = self.com.clone();
55
56        fabric_begin_end_proxy(
57            move |callback| unsafe {
58                com1.BeginGetNodeList(query_description, timeout_milliseconds, callback)
59            },
60            move |ctx| unsafe { com2.EndGetNodeList2(ctx) },
61            cancellation_token,
62        )
63    }
64
65    pub fn get_application_list_internal(
66        &self,
67        query_description: &FABRIC_APPLICATION_QUERY_DESCRIPTION,
68        timeout_milliseconds: u32,
69        cancellation_token: Option<BoxedCancelToken>,
70    ) -> FabricReceiver<crate::WinResult<IFabricGetApplicationListResult2>> {
71        let com1 = &self.com;
72        let com2 = self.com.clone();
73        fabric_begin_end_proxy(
74            move |callback| unsafe {
75                com1.BeginGetApplicationList(query_description, timeout_milliseconds, callback)
76            },
77            move |ctx| unsafe { com2.EndGetApplicationList2(ctx) },
78            cancellation_token,
79        )
80    }
81
82    fn get_service_list_internal(
83        &self,
84        desc: &FABRIC_SERVICE_QUERY_DESCRIPTION,
85        timeout_milliseconds: u32,
86        cancellation_token: Option<BoxedCancelToken>,
87    ) -> FabricReceiver<crate::WinResult<mssf_com::FabricClient::IFabricGetServiceListResult2>>
88    {
89        let com1 = &self.com;
90        let com2 = self.com.clone();
91        fabric_begin_end_proxy(
92            move |callback| unsafe {
93                com1.BeginGetServiceList(desc, timeout_milliseconds, callback)
94            },
95            move |ctx| unsafe { com2.EndGetServiceList2(ctx) },
96            cancellation_token,
97        )
98    }
99
100    fn get_partition_list_internal(
101        &self,
102        desc: &FABRIC_SERVICE_PARTITION_QUERY_DESCRIPTION,
103        timeout_milliseconds: u32,
104        cancellation_token: Option<BoxedCancelToken>,
105    ) -> FabricReceiver<crate::WinResult<IFabricGetPartitionListResult2>> {
106        let com1 = &self.com;
107        let com2 = self.com.clone();
108        fabric_begin_end_proxy(
109            move |callback| unsafe {
110                com1.BeginGetPartitionList(desc, timeout_milliseconds, callback)
111            },
112            move |ctx| unsafe { com2.EndGetPartitionList2(ctx) },
113            cancellation_token,
114        )
115    }
116
117    fn get_replica_list_internal(
118        &self,
119        desc: &FABRIC_SERVICE_REPLICA_QUERY_DESCRIPTION,
120        timeout_milliseconds: u32,
121        cancellation_token: Option<BoxedCancelToken>,
122    ) -> FabricReceiver<crate::WinResult<IFabricGetReplicaListResult2>> {
123        let com1 = &self.com;
124        let com2 = self.com.clone();
125        fabric_begin_end_proxy(
126            move |callback| unsafe {
127                com1.BeginGetReplicaList(desc, timeout_milliseconds, callback)
128            },
129            move |ctx| unsafe { com2.EndGetReplicaList2(ctx) },
130            cancellation_token,
131        )
132    }
133
134    fn get_partition_load_information_internal(
135        &self,
136        desc: &FABRIC_PARTITION_LOAD_INFORMATION_QUERY_DESCRIPTION,
137        timeout_milliseconds: u32,
138        cancellation_token: Option<BoxedCancelToken>,
139    ) -> FabricReceiver<crate::WinResult<IFabricGetPartitionLoadInformationResult>> {
140        let com1 = &self.com;
141        let com2 = self.com.clone();
142        fabric_begin_end_proxy(
143            move |callback| unsafe {
144                com1.BeginGetPartitionLoadInformation(desc, timeout_milliseconds, callback)
145            },
146            move |ctx| unsafe { com2.EndGetPartitionLoadInformation(ctx) },
147            cancellation_token,
148        )
149    }
150
151    fn get_deployed_replica_detail_internal(
152        &self,
153        desc: &FABRIC_DEPLOYED_SERVICE_REPLICA_DETAIL_QUERY_DESCRIPTION,
154        timeout_milliseconds: u32,
155        cancellation_token: Option<BoxedCancelToken>,
156    ) -> FabricReceiver<crate::WinResult<IFabricGetDeployedServiceReplicaDetailResult>> {
157        let com1 = &self.com;
158        let com2 = self.com.clone();
159        fabric_begin_end_proxy(
160            move |callback| unsafe {
161                com1.BeginGetDeployedReplicaDetail(desc, timeout_milliseconds, callback)
162            },
163            move |ctx| unsafe { com2.EndGetDeployedReplicaDetail(ctx) },
164            cancellation_token,
165        )
166    }
167}
168
169impl From<IFabricQueryClient13> for QueryClient {
170    fn from(com: IFabricQueryClient13) -> Self {
171        Self { com }
172    }
173}
174
175impl From<QueryClient> for IFabricQueryClient13 {
176    fn from(value: QueryClient) -> Self {
177        value.com
178    }
179}
180
181impl QueryClient {
182    // List nodes in the cluster
183    pub async fn get_node_list(
184        &self,
185        desc: &NodeQueryDescription,
186        timeout: Duration,
187        cancellation_token: Option<BoxedCancelToken>,
188    ) -> crate::Result<NodeListResult> {
189        let com = {
190            let mut pool = BoxPool::new();
191            let arg = desc.get_raw_with_pool(&mut pool);
192            self.get_node_list_internal(
193                &arg,
194                timeout.as_millis().try_into().unwrap(),
195                cancellation_token,
196            )
197        }
198        .await??;
199        Ok(NodeListResult::from(&com))
200    }
201
202    pub async fn get_application_list(
203        &self,
204        desc: &crate::types::ApplicationQueryDescription,
205        timeout: Duration,
206        cancellation_token: Option<BoxedCancelToken>,
207    ) -> crate::Result<crate::types::ApplicationListResult> {
208        let com = {
209            let mut pool = BoxPool::new();
210            let arg = desc.get_raw_with_pool(&mut pool);
211            self.get_application_list_internal(
212                &arg,
213                timeout.as_millis().try_into().unwrap(),
214                cancellation_token,
215            )
216        }
217        .await??;
218        Ok(crate::types::ApplicationListResult::from(&com))
219    }
220    pub async fn get_service_list(
221        &self,
222        desc: &ServiceQueryDescription,
223        timeout: Duration,
224        cancellation_token: Option<BoxedCancelToken>,
225    ) -> crate::Result<crate::types::ServiceListResult> {
226        let com = {
227            let mut pool = BoxPool::new();
228            let arg = desc.get_raw_with_pool(&mut pool);
229            self.get_service_list_internal(&arg, timeout.as_millis() as u32, cancellation_token)
230        }
231        .await??;
232        Ok(crate::types::ServiceListResult::from(&com))
233    }
234
235    pub async fn get_partition_list(
236        &self,
237        desc: &ServicePartitionQueryDescription,
238        timeout: Duration,
239        cancellation_token: Option<BoxedCancelToken>,
240    ) -> crate::Result<ServicePartitionList> {
241        let com = {
242            let raw: FABRIC_SERVICE_PARTITION_QUERY_DESCRIPTION = desc.into();
243            let mili = timeout.as_millis() as u32;
244            self.get_partition_list_internal(&raw, mili, cancellation_token)
245        }
246        .await??;
247        Ok(ServicePartitionList::from(&com))
248    }
249
250    pub async fn get_replica_list(
251        &self,
252        desc: &ServiceReplicaQueryDescription,
253        timeout: Duration,
254        cancellation_token: Option<BoxedCancelToken>,
255    ) -> crate::Result<ServiceReplicaList> {
256        let com = {
257            let raw: FABRIC_SERVICE_REPLICA_QUERY_DESCRIPTION = desc.into();
258            let mili = timeout.as_millis() as u32;
259            self.get_replica_list_internal(&raw, mili, cancellation_token)
260        }
261        .await??;
262        Ok(ServiceReplicaList::from(&com))
263    }
264
265    pub async fn get_partition_load_information(
266        &self,
267        desc: &PartitionLoadInformationQueryDescription,
268        timeout: Duration,
269        cancellation_token: Option<BoxedCancelToken>,
270    ) -> crate::Result<GetPartitionLoadInformationResult> {
271        let com = {
272            let raw: FABRIC_PARTITION_LOAD_INFORMATION_QUERY_DESCRIPTION = desc.into();
273            let timeout_ms = timeout.as_micros() as u32;
274            self.get_partition_load_information_internal(&raw, timeout_ms, cancellation_token)
275        }
276        .await??;
277        Ok(GetPartitionLoadInformationResult::from(&com))
278    }
279
280    pub async fn get_deployed_replica_detail(
281        &self,
282        desc: &DeployedServiceReplicaDetailQueryDescription,
283        timeout: Duration,
284        cancellation_token: Option<BoxedCancelToken>,
285    ) -> crate::Result<DeployedServiceReplicaDetailQueryResult> {
286        let com = {
287            let raw: FABRIC_DEPLOYED_SERVICE_REPLICA_DETAIL_QUERY_DESCRIPTION = desc.into();
288            let timeout_ms = timeout.as_micros() as u32;
289            self.get_deployed_replica_detail_internal(&raw, timeout_ms, cancellation_token)
290        }
291        .await??;
292        Ok(DeployedServiceReplicaDetailQueryResult::new(com))
293    }
294}