alopex_server/ops/
status.rs1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4
5use crate::metrics::Metrics;
6use crate::ops::recovery::RecoveryInfo;
7use crate::ops::state::{LifecycleStateManager, Mode, OperationState, RestoreMetadata};
8
9#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
10#[serde(rename_all = "snake_case")]
11pub enum OverallStatus {
12 Ok,
13 Degraded,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct StatusView {
18 pub overall_status: OverallStatus,
19 pub read_only: bool,
20 pub maintenance: bool,
21 pub recovery_state: RecoveryInfo,
22 pub backup_state: OperationState,
23 pub restore_state: OperationState,
24 pub restore_metadata: Option<RestoreMetadata>,
25 pub last_recovery_at_ms: Option<u64>,
26 pub last_backup_at_ms: Option<u64>,
27 pub last_restore_at_ms: Option<u64>,
28}
29
30#[derive(Debug, Clone)]
31pub struct StatusReporter {
32 lifecycle_state: Arc<LifecycleStateManager>,
33 recovery_info: RecoveryInfo,
34}
35
36impl StatusReporter {
37 pub fn new(lifecycle_state: Arc<LifecycleStateManager>, recovery_info: RecoveryInfo) -> Self {
38 Self {
39 lifecycle_state,
40 recovery_info,
41 }
42 }
43
44 pub fn status_view(&self) -> StatusView {
45 let mode = self.lifecycle_state.current_mode();
46 let read_only = mode == Mode::ReadOnly;
47 let maintenance = mode == Mode::Maintenance;
48 let overall_status = if read_only || maintenance {
49 OverallStatus::Degraded
50 } else {
51 OverallStatus::Ok
52 };
53
54 let backup_state = self.lifecycle_state.backup_state();
55 let restore_state = self.lifecycle_state.restore_state();
56 let restore_metadata = self.lifecycle_state.restore_metadata();
57 let last_recovery_at_ms = Some(self.recovery_info.finished_at_ms);
58 let last_backup_at_ms = backup_state.finished_at_ms;
59 let last_restore_at_ms = restore_metadata
60 .as_ref()
61 .map(|meta| meta.restored_at_ms)
62 .or(restore_state.finished_at_ms);
63
64 StatusView {
65 overall_status,
66 read_only,
67 maintenance,
68 recovery_state: self.recovery_info.clone(),
69 backup_state,
70 restore_state,
71 restore_metadata,
72 last_recovery_at_ms,
73 last_backup_at_ms,
74 last_restore_at_ms,
75 }
76 }
77
78 pub fn refresh_metrics(&self, metrics: &Metrics) {
79 let view = self.status_view();
80 metrics.record_operational_state(
81 &view.recovery_state,
82 &view.backup_state,
83 &view.restore_state,
84 );
85 }
86}