ic_timers/snapshot/
mod.rs1mod identity;
7mod metrics;
8mod model;
9
10pub use identity::{
11 MAX_TIMER_IDENTITY_COMPONENT_BYTES, TimerIdentity, TimerIdentityError, TimerIdentityField,
12};
13pub use metrics::{
14 MeasurementSummary, TimerCounters, TimerObservabilitySnapshot, TimerPerformance,
15};
16pub use model::{
17 DeclarationLifetime, InactiveReason, OrdinaryRuntimeStateSnapshot, TimerCompletion,
18 TimerCompletionOutcome, TimerControlFailure, TimerDirectiveSnapshot, TimerEpoch,
19 TimerLastOutcome, TimerOutcomeSnapshot, TimerPolicy, TimerProcessCondition,
20 TimerRegistrationStatus, TimerRunResult, TimerRuntimeStateSnapshot, TimerSchedulingMode,
21 WatchdogAttemptSnapshot, WatchdogAttemptStatus, WatchdogDecision, WatchdogRunResult,
22 WatchdogRuntimeStateSnapshot,
23};
24
25#[derive(Clone, Debug, Eq, PartialEq)]
27pub struct TimerSnapshot {
28 identity: TimerIdentity,
29 policy: TimerPolicy,
30 lifetime: DeclarationLifetime,
31 state: TimerRuntimeStateSnapshot,
32 scheduling_mode: TimerSchedulingMode,
33 latest_directive: Option<TimerDirectiveSnapshot>,
34 latest_requested_delay_ns: Option<u64>,
35 latest_armed_delay_ns: Option<u64>,
36 observability: TimerObservabilitySnapshot,
37}
38
39impl TimerSnapshot {
40 #[allow(clippy::too_many_arguments)] pub(crate) const fn new(
42 identity: TimerIdentity,
43 policy: TimerPolicy,
44 lifetime: DeclarationLifetime,
45 state: TimerRuntimeStateSnapshot,
46 scheduling_mode: TimerSchedulingMode,
47 latest_directive: Option<TimerDirectiveSnapshot>,
48 latest_requested_delay_ns: Option<u64>,
49 latest_armed_delay_ns: Option<u64>,
50 observability: &TimerObservabilitySnapshot,
51 ) -> Self {
52 Self {
53 identity,
54 policy,
55 lifetime,
56 state,
57 scheduling_mode,
58 latest_directive,
59 latest_requested_delay_ns,
60 latest_armed_delay_ns,
61 observability: *observability,
62 }
63 }
64
65 #[must_use]
67 pub const fn identity(&self) -> &TimerIdentity {
68 &self.identity
69 }
70
71 #[must_use]
73 pub const fn policy(&self) -> TimerPolicy {
74 self.policy
75 }
76
77 #[must_use]
79 pub const fn lifetime(&self) -> DeclarationLifetime {
80 self.lifetime
81 }
82
83 #[must_use]
85 pub const fn state(&self) -> TimerRuntimeStateSnapshot {
86 self.state
87 }
88
89 #[must_use]
95 pub const fn scheduling_mode(&self) -> TimerSchedulingMode {
96 self.scheduling_mode
97 }
98
99 #[must_use]
101 pub const fn latest_directive(&self) -> Option<TimerDirectiveSnapshot> {
102 self.latest_directive
103 }
104
105 #[must_use]
107 pub const fn latest_requested_delay_ns(&self) -> Option<u64> {
108 self.latest_requested_delay_ns
109 }
110
111 #[must_use]
113 pub const fn latest_armed_delay_ns(&self) -> Option<u64> {
114 self.latest_armed_delay_ns
115 }
116
117 #[must_use]
119 pub const fn next_deadline_ns(&self) -> Option<u64> {
120 self.state.next_deadline_ns()
121 }
122
123 #[must_use]
125 pub fn registration_status(&self) -> TimerRegistrationStatus {
126 self.state.into()
127 }
128
129 #[must_use]
131 pub const fn process_condition(&self) -> TimerProcessCondition {
132 match self.state {
133 TimerRuntimeStateSnapshot::Inactive {
134 reason: InactiveReason::Cancelled,
135 } => TimerProcessCondition::Disabled,
136 TimerRuntimeStateSnapshot::Inactive {
137 reason: InactiveReason::InvariantFailure | InactiveReason::ControlFailure(_),
138 } => TimerProcessCondition::Failed,
139 TimerRuntimeStateSnapshot::Inactive {
140 reason: InactiveReason::Stopped,
141 } if matches!(
142 self.observability.outcomes().last_outcome(),
143 Some(TimerLastOutcome::Completed(
144 TimerCompletionOutcome::RetryableFailure
145 ))
146 ) =>
147 {
148 TimerProcessCondition::Failed
149 }
150 TimerRuntimeStateSnapshot::Inactive { .. } => TimerProcessCondition::Idle,
151 TimerRuntimeStateSnapshot::Ordinary(_) | TimerRuntimeStateSnapshot::Watchdog(_)
152 if matches!(self.scheduling_mode, TimerSchedulingMode::Retry) =>
153 {
154 TimerProcessCondition::Retrying
155 }
156 TimerRuntimeStateSnapshot::Ordinary(_) | TimerRuntimeStateSnapshot::Watchdog(_) => {
157 TimerProcessCondition::Active
158 }
159 }
160 }
161
162 #[must_use]
164 pub const fn generation(&self) -> Option<u64> {
165 match self.state {
166 TimerRuntimeStateSnapshot::Inactive { .. } => None,
167 TimerRuntimeStateSnapshot::Ordinary(
168 OrdinaryRuntimeStateSnapshot::Scheduled { generation, .. }
169 | OrdinaryRuntimeStateSnapshot::Running { generation },
170 ) => Some(generation),
171 TimerRuntimeStateSnapshot::Watchdog(WatchdogRuntimeStateSnapshot::Scheduled {
172 scheduler_generation,
173 ..
174 }) => Some(scheduler_generation),
175 TimerRuntimeStateSnapshot::Watchdog(WatchdogRuntimeStateSnapshot::AwaitingWork {
176 successor_generation,
177 ..
178 }) => Some(successor_generation),
179 }
180 }
181
182 #[must_use]
184 pub const fn observability(&self) -> TimerObservabilitySnapshot {
185 self.observability
186 }
187}
188
189#[cfg(test)]
190mod tests;