1#![cfg_attr(
7 not(feature = "tokio_async"),
8 allow(dead_code, reason = "code configured out")
9)]
10
11use std::{ffi::c_void, marker::PhantomData};
12
13use mssf_com::FabricTypes::{
14 FABRIC_NAMED_REPARTITION_DESCRIPTION, FABRIC_SERVICE_DESCRIPTION,
15 FABRIC_SERVICE_DESCRIPTION_KIND_STATEFUL, FABRIC_SERVICE_DESCRIPTION_KIND_STATELESS,
16 FABRIC_SERVICE_PARTITION_KIND, FABRIC_SERVICE_PARTITION_KIND_INVALID,
17 FABRIC_SERVICE_PARTITION_KIND_NAMED, FABRIC_SERVICE_UPDATE_DESCRIPTION,
18 FABRIC_STATEFUL_SERVICE_DESCRIPTION, FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX1,
19 FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX2, FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX3,
20 FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX4, FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION,
21 FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX1, FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX2,
22 FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX3, FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX4,
23 FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX5, FABRIC_STATELESS_SERVICE_DESCRIPTION,
24 FABRIC_STATELESS_SERVICE_DESCRIPTION_EX1, FABRIC_STATELESS_SERVICE_DESCRIPTION_EX2,
25 FABRIC_STATELESS_SERVICE_DESCRIPTION_EX3, FABRIC_STATELESS_SERVICE_DESCRIPTION_EX4,
26 FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION, FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION_EX1,
27 FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION_EX2,
28 FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION_EX3, FABRIC_URI,
29};
30use windows_core::{WString, PCWSTR};
31
32use crate::types::{MoveCost, PartitionSchemeDescription, ServicePackageActivationMode, Uri};
33
34pub enum ServiceDescription {
35 Stateful(StatefulServiceDescription), Stateless(StatelessServiceDescription), }
39
40#[derive(Debug)]
41pub struct StatefulServiceDescription {
42 application_name: Uri,
46 service_name: Uri,
47 service_type_name: WString,
48 initialization_data: Option<Vec<u8>>,
49 partition_scheme: PartitionSchemeDescription,
50 min_replica_set_size: i32,
52 target_replica_set_size: i32,
53 placement_contraints: WString,
55 _correlations: Vec<WString>, _metrics: Vec<WString>, has_persistent_state: bool,
58 _policy_list: Vec<WString>, _failover_settings: WString, default_move_cost: Option<MoveCost>, service_package_activation_mode: ServicePackageActivationMode,
65 _service_dns_name: Option<WString>, _service_scaling_policys: Vec<WString>, }
69
70impl StatefulServiceDescription {
71 pub fn new(
74 application_name: Uri,
75 service_name: Uri,
76 service_type_name: WString,
77 partition_scheme: PartitionSchemeDescription,
78 ) -> Self {
79 Self {
80 application_name,
81 service_name,
82 service_type_name,
83 initialization_data: None,
84 partition_scheme,
85 min_replica_set_size: 1,
86 target_replica_set_size: 1,
87 placement_contraints: WString::default(),
88 _correlations: Vec::new(),
89 _metrics: Vec::new(),
90 has_persistent_state: false,
91 _policy_list: Vec::new(),
92 _failover_settings: WString::default(),
93 default_move_cost: None,
94 service_package_activation_mode: ServicePackageActivationMode::default(),
95 _service_dns_name: None,
96 _service_scaling_policys: Vec::new(),
97 }
98 }
99
100 pub fn with_initialization_data(mut self, initialization_data: Vec<u8>) -> Self {
103 self.initialization_data = Some(initialization_data);
104 self
105 }
106
107 pub fn with_min_replica_set_size(mut self, min_replica_set_size: i32) -> Self {
108 self.min_replica_set_size = min_replica_set_size;
109 self
110 }
111 pub fn with_target_replica_set_size(mut self, target_replica_set_size: i32) -> Self {
112 self.target_replica_set_size = target_replica_set_size;
113 self
114 }
115 pub fn with_has_persistent_state(mut self, has_persistent_state: bool) -> Self {
116 self.has_persistent_state = has_persistent_state;
117 self
118 }
119
120 pub fn with_default_move_cost(mut self, default_move_cost: MoveCost) -> Self {
121 self.default_move_cost = Some(default_move_cost);
122 self
123 }
124 pub fn with_service_activation_mode(
125 mut self,
126 service_package_activation_mode: ServicePackageActivationMode,
127 ) -> Self {
128 self.service_package_activation_mode = service_package_activation_mode;
129 self
130 }
131}
132
133pub(crate) struct StatefulServiceDescriptionRaw<'a> {
134 internal: Box<FABRIC_STATEFUL_SERVICE_DESCRIPTION>,
135 _internal_ex1: Box<FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX1>,
136 _internal_ex2: Box<FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX2>,
137 _internal_ex3: Box<FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX3>,
138 _internal_ex4: Box<FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX4>,
139 phantom: PhantomData<&'a StatefulServiceDescription>,
140}
141
142impl StatefulServiceDescriptionRaw<'_> {
143 pub fn as_ffi(&self) -> &FABRIC_STATEFUL_SERVICE_DESCRIPTION {
144 self.internal.as_ref()
145 }
146}
147
148impl StatefulServiceDescription {
149 fn build_raw(&self) -> StatefulServiceDescriptionRaw {
151 let ex4 = Box::new(FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX4 {
152 ServiceScalingPolicies: std::ptr::null_mut(), ScalingPolicyCount: 0,
154 Reserved: std::ptr::null_mut(),
155 });
156 let ex3 = Box::new(FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX3 {
157 ServiceDnsName: windows_core::PCWSTR::null(), ServicePackageActivationMode: self.service_package_activation_mode.clone().into(),
159 Reserved: ex4.as_ref() as *const _ as *mut c_void,
160 });
161 let ex2 = Box::new(FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX2 {
162 IsDefaultMoveCostSpecified: self.default_move_cost.is_some(),
163 DefaultMoveCost: self
164 .default_move_cost
165 .clone()
166 .unwrap_or(MoveCost::Zero)
167 .into(),
168 Reserved: ex3.as_ref() as *const _ as *mut c_void,
169 });
170 let ex1 = Box::new(FABRIC_STATEFUL_SERVICE_DESCRIPTION_EX1 {
171 PolicyList: std::ptr::null_mut(), FailoverSettings: std::ptr::null_mut(), Reserved: ex2.as_ref() as *const _ as *mut c_void,
174 });
175
176 let (init_data, init_data_len) = self
177 .initialization_data
178 .as_ref()
179 .map(|v| (v.as_ptr() as *mut u8, v.len() as u32))
180 .unwrap_or((std::ptr::null_mut(), 0));
181
182 let internal = Box::new(FABRIC_STATEFUL_SERVICE_DESCRIPTION {
183 ApplicationName: self.application_name.as_raw(),
184 ServiceName: self.service_name.as_raw(),
185 ServiceTypeName: self.service_type_name.as_pcwstr(),
186 InitializationDataSize: init_data_len,
187 InitializationData: init_data,
188 PartitionScheme: self.partition_scheme.as_raw().0,
189 PartitionSchemeDescription: self.partition_scheme.as_raw().1,
190 TargetReplicaSetSize: self.target_replica_set_size,
191 MinReplicaSetSize: self.min_replica_set_size,
192 PlacementConstraints: self.placement_contraints.as_pcwstr(), CorrelationCount: 0,
194 Correlations: std::ptr::null_mut(), Metrics: std::ptr::null_mut(), MetricCount: 0,
197 HasPersistedState: self.has_persistent_state,
198 Reserved: ex1.as_ref() as *const _ as *mut c_void,
199 });
200
201 StatefulServiceDescriptionRaw {
202 internal,
203 _internal_ex1: ex1,
204 _internal_ex2: ex2,
205 _internal_ex3: ex3,
206 _internal_ex4: ex4,
207 phantom: PhantomData,
208 }
209 }
210}
211
212pub struct StatelessServiceDescription {
213 application_name: WString,
215 service_name: WString,
216 service_type_name: WString,
217 initialization_data: Option<Vec<u8>>,
218 partition_scheme_description: PartitionSchemeDescription,
219 instance_count: i32,
221 placement_contraints: WString,
223 _correlations: Vec<WString>, _metrics: Vec<WString>, _policy_list: Vec<WString>, default_move_cost: Option<MoveCost>, service_package_activation_mode: ServicePackageActivationMode, _service_dns_name: WString, _service_scaling_policys: Vec<WString>, }
235impl StatelessServiceDescription {
236 pub fn new(
237 application_name: WString,
238 service_name: WString,
239 service_type_name: WString,
240 partition_scheme_description: PartitionSchemeDescription,
241 ) -> Self {
242 Self {
243 application_name,
244 service_name,
245 service_type_name,
246 initialization_data: None,
247 partition_scheme_description,
248 instance_count: 1,
249 placement_contraints: WString::default(),
250 _correlations: Vec::new(),
251 _metrics: Vec::new(),
252 _policy_list: Vec::new(),
253 default_move_cost: None,
254 service_package_activation_mode: ServicePackageActivationMode::default(),
255 _service_dns_name: WString::default(),
256 _service_scaling_policys: Vec::new(),
257 }
258 }
259
260 pub fn with_initialization_data(mut self, initialization_data: Vec<u8>) -> Self {
261 self.initialization_data = Some(initialization_data);
262 self
263 }
264 pub fn with_instance_count(mut self, instance_count: i32) -> Self {
265 self.instance_count = instance_count;
266 self
267 }
268 pub fn with_placement_constraints(mut self, placement_contraints: WString) -> Self {
269 self.placement_contraints = placement_contraints;
270 self
271 }
272 pub fn with_default_move_cost(mut self, default_move_cost: MoveCost) -> Self {
273 self.default_move_cost = Some(default_move_cost);
274 self
275 }
276 pub fn with_service_activation_mode(
277 mut self,
278 service_package_activation_mode: ServicePackageActivationMode,
279 ) -> Self {
280 self.service_package_activation_mode = service_package_activation_mode;
281 self
282 }
283}
284pub(crate) struct StatelessServiceDescriptionRaw<'a> {
285 internal: Box<FABRIC_STATELESS_SERVICE_DESCRIPTION>,
286 _internal_ex1: Box<FABRIC_STATELESS_SERVICE_DESCRIPTION_EX1>,
287 _internal_ex2: Box<FABRIC_STATELESS_SERVICE_DESCRIPTION_EX2>,
288 _internal_ex3: Box<FABRIC_STATELESS_SERVICE_DESCRIPTION_EX3>,
289 _internal_ex4: Box<FABRIC_STATELESS_SERVICE_DESCRIPTION_EX4>,
290 phantom: PhantomData<&'a StatelessServiceDescription>,
291}
292impl StatelessServiceDescriptionRaw<'_> {
293 pub fn as_ffi(&self) -> &FABRIC_STATELESS_SERVICE_DESCRIPTION {
294 self.internal.as_ref()
295 }
296}
297
298impl StatelessServiceDescription {
299 fn build_raw(&self) -> StatelessServiceDescriptionRaw {
300 let ex4 = Box::new(FABRIC_STATELESS_SERVICE_DESCRIPTION_EX4 {
301 ServiceScalingPolicies: std::ptr::null_mut(), ScalingPolicyCount: 0,
303 Reserved: std::ptr::null_mut(),
304 });
305 let ex3 = Box::new(FABRIC_STATELESS_SERVICE_DESCRIPTION_EX3 {
306 ServiceDnsName: windows_core::PCWSTR::null(), ServicePackageActivationMode: self.service_package_activation_mode.clone().into(),
308 Reserved: ex4.as_ref() as *const _ as *mut c_void,
309 });
310 let ex2 = Box::new(FABRIC_STATELESS_SERVICE_DESCRIPTION_EX2 {
311 IsDefaultMoveCostSpecified: self.default_move_cost.is_some(),
312 DefaultMoveCost: self
313 .default_move_cost
314 .clone()
315 .unwrap_or(MoveCost::Zero)
316 .into(),
317 Reserved: ex3.as_ref() as *const _ as *mut c_void,
318 });
319 let ex1 = Box::new(FABRIC_STATELESS_SERVICE_DESCRIPTION_EX1 {
320 PolicyList: std::ptr::null_mut(), Reserved: ex2.as_ref() as *const _ as *mut c_void,
322 });
323
324 let (init_data, init_data_len) = self
325 .initialization_data
326 .as_ref()
327 .map(|v| (v.as_ptr() as *mut u8, v.len() as u32))
328 .unwrap_or((std::ptr::null_mut(), 0));
329
330 let internal = Box::new(FABRIC_STATELESS_SERVICE_DESCRIPTION {
331 ApplicationName: FABRIC_URI(self.application_name.as_ptr() as *mut u16),
332 ServiceName: FABRIC_URI(self.service_name.as_ptr() as *mut u16),
333 ServiceTypeName: self.service_type_name.as_pcwstr(),
334 InitializationDataSize: init_data_len,
335 InitializationData: init_data,
336 PartitionScheme: self.partition_scheme_description.as_raw().0,
337 PartitionSchemeDescription: self.partition_scheme_description.as_raw().1,
338 InstanceCount: self.instance_count,
339 PlacementConstraints: self.placement_contraints.as_pcwstr(), CorrelationCount: 0,
341 Correlations: std::ptr::null_mut(), Metrics: std::ptr::null_mut(), MetricCount: 0,
344 Reserved: ex1.as_ref() as *const _ as *mut c_void,
345 });
346 StatelessServiceDescriptionRaw {
347 internal,
348 _internal_ex1: ex1,
349 _internal_ex2: ex2,
350 _internal_ex3: ex3,
351 _internal_ex4: ex4,
352 phantom: PhantomData,
353 }
354 }
355}
356
357pub(crate) enum ServiceDescriptionRaw<'a> {
358 Stateful(StatefulServiceDescriptionRaw<'a>),
359 Stateless(StatelessServiceDescriptionRaw<'a>),
360}
361
362impl ServiceDescriptionRaw<'_> {
363 pub(crate) fn as_ffi(&self) -> FABRIC_SERVICE_DESCRIPTION {
364 match self {
365 ServiceDescriptionRaw::Stateful(ref desc) => FABRIC_SERVICE_DESCRIPTION {
366 Kind: FABRIC_SERVICE_DESCRIPTION_KIND_STATEFUL,
367 Value: desc.as_ffi() as *const _ as *mut c_void,
368 },
369 ServiceDescriptionRaw::Stateless(ref desc) => FABRIC_SERVICE_DESCRIPTION {
370 Kind: FABRIC_SERVICE_DESCRIPTION_KIND_STATELESS,
371 Value: desc.as_ffi() as *const _ as *mut c_void,
372 },
373 }
374 }
375}
376
377impl ServiceDescription {
378 pub(crate) fn build_raw(&self) -> ServiceDescriptionRaw {
381 match self {
382 ServiceDescription::Stateful(ref desc) => {
383 ServiceDescriptionRaw::Stateful(desc.build_raw())
384 }
385 ServiceDescription::Stateless(ref desc) => {
386 ServiceDescriptionRaw::Stateless(desc.build_raw())
387 }
388 }
389 }
390}
391
392#[derive(Debug, Default)]
396pub enum ServiceRepartitionDescription {
397 #[default]
398 Invalid,
399 Named(NamedRepartitionDescription), }
401
402#[derive(Debug)]
404pub struct NamedRepartitionDescription {
405 pub names_to_add: Vec<WString>,
406 pub names_to_remove: Vec<WString>,
407}
408
409pub(crate) struct NamedRepartitionDescriptionRaw<'a> {
411 _names_to_add: Vec<PCWSTR>,
412 _names_to_remove: Vec<PCWSTR>,
413 internal: Box<FABRIC_NAMED_REPARTITION_DESCRIPTION>,
414 phantom: PhantomData<&'a NamedRepartitionDescription>,
415}
416
417impl NamedRepartitionDescription {
418 pub(crate) fn as_raw(&self) -> NamedRepartitionDescriptionRaw {
419 let names_to_add = self
420 .names_to_add
421 .iter()
422 .map(|s| s.as_pcwstr())
423 .collect::<Vec<_>>();
424 let names_to_remove = self
425 .names_to_remove
426 .iter()
427 .map(|s| s.as_pcwstr())
428 .collect::<Vec<_>>();
429 let internal = Box::new(FABRIC_NAMED_REPARTITION_DESCRIPTION {
430 NamesToAddCount: names_to_add.len() as u32,
431 NamesToAdd: names_to_add.as_ptr(),
432 NamesToRemoveCount: names_to_remove.len() as u32,
433 NamesToRemove: names_to_remove.as_ptr(),
434 Reserved: std::ptr::null_mut(),
435 });
436 NamedRepartitionDescriptionRaw {
437 _names_to_add: names_to_add,
438 _names_to_remove: names_to_remove,
439 internal,
440 phantom: PhantomData,
441 }
442 }
443}
444
445impl NamedRepartitionDescriptionRaw<'_> {
446 pub(crate) fn as_ffi(&self) -> &FABRIC_NAMED_REPARTITION_DESCRIPTION {
447 self.internal.as_ref()
448 }
449}
450
451pub(crate) enum ServiceRepartitionDescriptionRaw<'a> {
453 Invalid,
454 Named(NamedRepartitionDescriptionRaw<'a>),
455}
456
457impl ServiceRepartitionDescription {
458 pub(crate) fn as_raw(&self) -> ServiceRepartitionDescriptionRaw {
459 match self {
460 ServiceRepartitionDescription::Named(ref desc) => {
461 ServiceRepartitionDescriptionRaw::Named(desc.as_raw())
462 }
463 ServiceRepartitionDescription::Invalid => ServiceRepartitionDescriptionRaw::Invalid,
464 }
465 }
466}
467
468impl ServiceRepartitionDescriptionRaw<'_> {
469 pub(crate) fn as_ffi(&self) -> (FABRIC_SERVICE_PARTITION_KIND, *const c_void) {
470 match self {
471 ServiceRepartitionDescriptionRaw::Named(ref desc) => (
472 FABRIC_SERVICE_PARTITION_KIND_NAMED,
473 desc.as_ffi() as *const _ as *const _,
474 ),
475 ServiceRepartitionDescriptionRaw::Invalid => {
476 (FABRIC_SERVICE_PARTITION_KIND_INVALID, std::ptr::null_mut())
477 }
478 }
479 }
480}
481
482bitflags::bitflags! {
483 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
486 pub struct StatefulServiceUpdateDescriptionFlags: u32 {
487 const FABRIC_STATEFUL_SERVICE_NONE = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_NONE.0 as u32;
488 const FABRIC_STATEFUL_SERVICE_TARGET_REPLICA_SET_SIZE = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_TARGET_REPLICA_SET_SIZE.0 as u32;
489 const FABRIC_STATEFUL_SERVICE_REPLICA_RESTART_WAIT_DURATION = mssf_com::FabricTypes::FABRIC_STATELESS_SERVICE_CORRELATIONS.0 as u32;
490 const FABRIC_STATEFUL_SERVICE_QUORUM_LOSS_WAIT_DURATION = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_QUORUM_LOSS_WAIT_DURATION.0 as u32;
491 const FABRIC_STATEFUL_SERVICE_STANDBY_REPLICA_KEEP_DURATION = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_STANDBY_REPLICA_KEEP_DURATION.0 as u32;
492 const FABRIC_STATEFUL_SERVICE_MIN_REPLICA_SET_SIZE = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_MIN_REPLICA_SET_SIZE.0 as u32;
493 const FABRIC_STATEFUL_SERVICE_PLACEMENT_CONSTRAINTS = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_PLACEMENT_CONSTRAINTS.0 as u32;
494 const FABRIC_STATEFUL_SERVICE_POLICY_LIST = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_POLICY_LIST.0 as u32;
495 const FABRIC_STATEFUL_SERVICE_CORRELATIONS = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_CORRELATIONS.0 as u32;
496 const FABRIC_STATEFUL_SERVICE_METRICS = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_METRICS.0 as u32;
497 const FABRIC_STATEFUL_SERVICE_MOVE_COST = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_MOVE_COST.0 as u32;
498 const FABRIC_STATEFUL_SERVICE_SCALING_POLICY = mssf_com::FabricTypes::FABRIC_STATEFUL_SERVICE_SCALING_POLICY.0 as u32;
499 }
500}
501impl Default for StatefulServiceUpdateDescriptionFlags {
502 fn default() -> Self {
503 StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_NONE
504 }
505}
506
507pub enum ServiceUpdateDescription {
509 Stateful(StatefulServiceUpdateDescription), Stateless(StatelessServiceUpdateDescription), }
512
513impl ServiceUpdateDescription {
514 pub(crate) fn build_raw(&self) -> ServiceUpdateDescriptionRaw {
517 match self {
518 ServiceUpdateDescription::Stateful(ref desc) => {
519 ServiceUpdateDescriptionRaw::Stateful(desc.build_raw())
520 }
521 ServiceUpdateDescription::Stateless(ref desc) => {
522 ServiceUpdateDescriptionRaw::Stateless(desc.build_raw())
523 }
524 }
525 }
526}
527
528#[derive(Debug, Default)]
530pub struct StatefulServiceUpdateDescription {
531 flags: StatefulServiceUpdateDescriptionFlags,
532 target_replica_set_size: i32,
533 replica_restart_wait_duration_seconds: u32,
534 quorum_loss_wait_duration_seconds: u32,
535 stand_by_replica_keep_duration_seconds: u32,
537 min_replica_set_size: i32,
539 placement_contraints: WString,
541 _policy_list: Vec<WString>, _correlations: Vec<WString>, _metrics: Vec<WString>, default_move_cost: MoveCost, repartition_description: ServiceRepartitionDescription,
548 _scaling_policys: Vec<WString>, }
550
551impl StatefulServiceUpdateDescription {
553 pub fn new() -> Self {
554 Self::default()
555 }
556
557 pub fn with_target_replica_set_size(mut self, target_replica_set_size: i32) -> Self {
558 self.flags |=
559 StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_TARGET_REPLICA_SET_SIZE;
560 self.target_replica_set_size = target_replica_set_size;
561 self
562 }
563
564 pub fn with_replica_restart_wait_duration_seconds(
565 mut self,
566 replica_restart_wait_duration_seconds: u32,
567 ) -> Self {
568 self.flags |= StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_REPLICA_RESTART_WAIT_DURATION;
569 self.replica_restart_wait_duration_seconds = replica_restart_wait_duration_seconds;
570 self
571 }
572 pub fn with_quorum_loss_wait_duration_seconds(
573 mut self,
574 quorum_loss_wait_duration_seconds: u32,
575 ) -> Self {
576 self.flags |= StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_QUORUM_LOSS_WAIT_DURATION;
577 self.quorum_loss_wait_duration_seconds = quorum_loss_wait_duration_seconds;
578 self
579 }
580 pub fn with_stand_by_replica_keep_duration_seconds(
581 mut self,
582 stand_by_replica_keep_duration_seconds: u32,
583 ) -> Self {
584 self.flags |= StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_STANDBY_REPLICA_KEEP_DURATION;
585 self.stand_by_replica_keep_duration_seconds = stand_by_replica_keep_duration_seconds;
586 self
587 }
588 pub fn with_min_replica_set_size(mut self, min_replica_set_size: i32) -> Self {
589 self.flags |=
590 StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_MIN_REPLICA_SET_SIZE;
591 self.min_replica_set_size = min_replica_set_size;
592 self
593 }
594
595 pub fn with_move_cost(mut self, default_move_cost: MoveCost) -> Self {
596 self.flags |= StatefulServiceUpdateDescriptionFlags::FABRIC_STATEFUL_SERVICE_MOVE_COST;
597 self.default_move_cost = default_move_cost;
598 self
599 }
600
601 pub fn with_repartition_description(
602 mut self,
603 repartition_description: ServiceRepartitionDescription,
604 ) -> Self {
605 self.repartition_description = repartition_description;
607 self
608 }
609}
610
611pub struct StatelessServiceUpdateDescription {
613 pub flags: StatefulServiceUpdateDescriptionFlags,
614 pub instance_count: i32,
615 pub placement_contraints: WString,
617 pub policy_list: Vec<WString>, pub correlations: Vec<WString>, pub metrics: Vec<WString>, pub default_move_cost: Option<MoveCost>, pub repartition_description: PartitionSchemeDescription, pub scaling_policys: Vec<WString>, }
626
627impl StatelessServiceUpdateDescription {
628 fn build_raw(&self) -> StatelessServiceUpdateDescriptionRaw {
629 unimplemented!()
630 }
631}
632
633pub(crate) enum ServiceUpdateDescriptionRaw<'a> {
635 Stateful(StatefulServiceUpdateDescriptionRaw<'a>),
636 Stateless(StatelessServiceUpdateDescriptionRaw),
637}
638
639pub(crate) struct StatefulServiceUpdateDescriptionRaw<'a> {
641 internal: Box<FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION>,
642 _internal_ex1: Box<FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX1>,
643 _internal_ex2: Box<FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX2>,
644 _internal_ex3: Box<FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX3>,
645 _internal_ex4: Box<FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX4>,
646 _internal_ex5: Box<FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX5>,
647 _repartition_owner: ServiceRepartitionDescriptionRaw<'a>,
648}
649
650impl StatefulServiceUpdateDescriptionRaw<'_> {
651 pub(crate) fn as_ffi(&self) -> &FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION {
652 self.internal.as_ref()
653 }
654}
655
656pub(crate) struct StatelessServiceUpdateDescriptionRaw {
657 _internal: Box<FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION>,
658 _internal_ex1: Box<FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION_EX1>,
659 _internal_ex2: Box<FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION_EX2>,
660 _internal_ex3: Box<FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION_EX3>,
661}
662
663impl StatelessServiceUpdateDescriptionRaw {
664 pub(crate) fn as_ffi(&self) -> &FABRIC_STATELESS_SERVICE_UPDATE_DESCRIPTION {
666 unimplemented!()
667 }
669}
670
671impl ServiceUpdateDescriptionRaw<'_> {
672 pub(crate) fn as_ffi(&self) -> FABRIC_SERVICE_UPDATE_DESCRIPTION {
674 match self {
675 ServiceUpdateDescriptionRaw::Stateful(ref desc) => FABRIC_SERVICE_UPDATE_DESCRIPTION {
676 Kind: FABRIC_SERVICE_DESCRIPTION_KIND_STATEFUL,
677 Value: desc.as_ffi() as *const _ as *mut c_void,
678 },
679 ServiceUpdateDescriptionRaw::Stateless(ref desc) => FABRIC_SERVICE_UPDATE_DESCRIPTION {
680 Kind: FABRIC_SERVICE_DESCRIPTION_KIND_STATELESS,
681 Value: desc.as_ffi() as *const _ as *mut c_void,
682 },
683 }
684 }
685}
686
687impl StatefulServiceUpdateDescription {
688 pub(crate) fn build_raw(&self) -> StatefulServiceUpdateDescriptionRaw {
689 let repartition_raw = self.repartition_description.as_raw();
690 let ex5 = Box::new(FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX5 {
691 RepartitionDescription: repartition_raw.as_ffi().1 as *const _ as *mut _,
692 RepartitionKind: repartition_raw.as_ffi().0,
693 ScalingPolicyCount: 0,
694 ServiceScalingPolicies: std::ptr::null_mut(), Reserved: std::ptr::null_mut(),
696 });
697 let ex4 = Box::new(FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX4 {
698 DefaultMoveCost: self.default_move_cost.clone().into(),
699 Reserved: ex5.as_ref() as *const _ as *mut c_void,
700 });
701 let ex3 = Box::new(FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX3 {
702 PlacementConstraints: self.placement_contraints.as_pcwstr(), PolicyList: std::ptr::null_mut(), CorrelationCount: 0,
705 Correlations: std::ptr::null_mut(), Metrics: std::ptr::null_mut(), MetricCount: 0,
708 Reserved: ex4.as_ref() as *const _ as *mut c_void,
709 });
710 let ex2 = Box::new(FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX2 {
711 MinReplicaSetSize: self.min_replica_set_size,
712 Reserved: ex3.as_ref() as *const _ as *mut c_void,
713 });
714 let ex1 = Box::new(FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION_EX1 {
715 StandByReplicaKeepDurationSeconds: self.stand_by_replica_keep_duration_seconds,
716 Reserved: ex2.as_ref() as *const _ as *mut c_void,
717 });
718
719 let internal = Box::new(FABRIC_STATEFUL_SERVICE_UPDATE_DESCRIPTION {
720 Flags: self.flags.bits(),
721 TargetReplicaSetSize: self.target_replica_set_size,
722 ReplicaRestartWaitDurationSeconds: self.replica_restart_wait_duration_seconds,
723 QuorumLossWaitDurationSeconds: self.quorum_loss_wait_duration_seconds,
724 Reserved: ex1.as_ref() as *const _ as *mut c_void,
725 });
726
727 StatefulServiceUpdateDescriptionRaw {
728 internal,
729 _internal_ex1: ex1,
730 _internal_ex2: ex2,
731 _internal_ex3: ex3,
732 _internal_ex4: ex4,
733 _internal_ex5: ex5,
734 _repartition_owner: repartition_raw,
735 }
736 }
737}