Skip to main content

canic_backup/restore/apply/journal/
counts.rs

1use super::{
2    RestoreApplyDryRunOperation, RestoreApplyJournalError, RestoreApplyJournalOperation,
3    RestoreApplyOperationKind, RestoreApplyOperationState, validate_apply_journal_count,
4};
5use serde::{Deserialize, Serialize};
6
7///
8/// RestoreApplyJournalStateCounts
9///
10
11#[derive(Clone, Debug, Default, Eq, PartialEq)]
12pub(super) struct RestoreApplyJournalStateCounts {
13    pub(super) pending: usize,
14    pub(super) ready: usize,
15    pub(super) blocked: usize,
16    pub(super) completed: usize,
17    pub(super) failed: usize,
18}
19
20impl RestoreApplyJournalStateCounts {
21    // Count operation states from concrete journal operation rows.
22    pub(super) fn from_operations(operations: &[RestoreApplyJournalOperation]) -> Self {
23        let mut counts = Self::default();
24        for operation in operations {
25            match operation.state {
26                RestoreApplyOperationState::Pending => counts.pending += 1,
27                RestoreApplyOperationState::Ready => counts.ready += 1,
28                RestoreApplyOperationState::Blocked => counts.blocked += 1,
29                RestoreApplyOperationState::Completed => counts.completed += 1,
30                RestoreApplyOperationState::Failed => counts.failed += 1,
31            }
32        }
33        counts
34    }
35}
36
37///
38/// RestoreApplyOperationKindCounts
39///
40
41#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
42pub struct RestoreApplyOperationKindCounts {
43    #[serde(default)]
44    pub canister_stops: usize,
45    #[serde(default)]
46    pub canister_starts: usize,
47    pub snapshot_uploads: usize,
48    pub snapshot_loads: usize,
49    pub member_verifications: usize,
50    pub fleet_verifications: usize,
51    pub verification_operations: usize,
52}
53
54impl RestoreApplyOperationKindCounts {
55    /// Count restore apply journal operations by runner operation kind.
56    #[must_use]
57    pub fn from_operations(operations: &[RestoreApplyJournalOperation]) -> Self {
58        let mut counts = Self::default();
59        for operation in operations {
60            counts.record(&operation.operation);
61        }
62        counts
63    }
64
65    /// Validate this count object against concrete operations.
66    pub fn validate_matches(&self, expected: &Self) -> Result<(), RestoreApplyJournalError> {
67        validate_apply_journal_count(
68            "operation_counts.canister_stops",
69            self.canister_stops,
70            expected.canister_stops,
71        )?;
72        validate_apply_journal_count(
73            "operation_counts.canister_starts",
74            self.canister_starts,
75            expected.canister_starts,
76        )?;
77        validate_apply_journal_count(
78            "operation_counts.snapshot_uploads",
79            self.snapshot_uploads,
80            expected.snapshot_uploads,
81        )?;
82        validate_apply_journal_count(
83            "operation_counts.snapshot_loads",
84            self.snapshot_loads,
85            expected.snapshot_loads,
86        )?;
87        validate_apply_journal_count(
88            "operation_counts.member_verifications",
89            self.member_verifications,
90            expected.member_verifications,
91        )?;
92        validate_apply_journal_count(
93            "operation_counts.fleet_verifications",
94            self.fleet_verifications,
95            expected.fleet_verifications,
96        )?;
97        validate_apply_journal_count(
98            "operation_counts.verification_operations",
99            self.verification_operations,
100            expected.verification_operations,
101        )
102    }
103
104    /// Count restore apply dry-run operations by runner operation kind.
105    #[must_use]
106    pub fn from_dry_run_operations(operations: &[RestoreApplyDryRunOperation]) -> Self {
107        let mut counts = Self::default();
108        for operation in operations {
109            counts.record(&operation.operation);
110        }
111        counts
112    }
113
114    // Record one operation kind in the aggregate count object.
115    const fn record(&mut self, operation: &RestoreApplyOperationKind) {
116        match operation {
117            RestoreApplyOperationKind::StopCanister => self.canister_stops += 1,
118            RestoreApplyOperationKind::StartCanister => self.canister_starts += 1,
119            RestoreApplyOperationKind::UploadSnapshot => self.snapshot_uploads += 1,
120            RestoreApplyOperationKind::LoadSnapshot => self.snapshot_loads += 1,
121            RestoreApplyOperationKind::VerifyMember => {
122                self.member_verifications += 1;
123                self.verification_operations += 1;
124            }
125            RestoreApplyOperationKind::VerifyFleet => {
126                self.fleet_verifications += 1;
127                self.verification_operations += 1;
128            }
129        }
130    }
131}