oris_execution_runtime/
recovery.rs1use oris_kernel::identity::RunId;
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub enum RecoveryStep {
15 LeaseExpired,
17 CheckpointReload,
19 Replay,
21 ReadyForDispatch,
23}
24
25impl RecoveryStep {
26 pub fn pipeline() -> &'static [RecoveryStep] {
28 &[
29 RecoveryStep::LeaseExpired,
30 RecoveryStep::CheckpointReload,
31 RecoveryStep::Replay,
32 RecoveryStep::ReadyForDispatch,
33 ]
34 }
35}
36
37#[derive(Clone, Debug, Default)]
39pub struct RecoveryContext {
40 pub attempt_id: String,
41 pub run_id: RunId,
42}
43
44impl RecoveryContext {
45 pub fn new(attempt_id: impl Into<String>, run_id: impl Into<RunId>) -> Self {
46 Self {
47 attempt_id: attempt_id.into(),
48 run_id: run_id.into(),
49 }
50 }
51}
52
53#[derive(Clone, Debug)]
59pub struct CrashRecoveryPipeline {
60 pub attempt_id: String,
61 pub run_id: RunId,
62}
63
64impl CrashRecoveryPipeline {
65 pub fn new(attempt_id: impl Into<String>, run_id: impl Into<RunId>) -> Self {
66 Self {
67 attempt_id: attempt_id.into(),
68 run_id: run_id.into(),
69 }
70 }
71
72 pub fn steps() -> &'static [RecoveryStep] {
74 RecoveryStep::pipeline()
75 }
76
77 pub fn replay_context(&self) -> RecoveryContext {
79 RecoveryContext::new(&self.attempt_id, &self.run_id)
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn recovery_step_pipeline_order() {
89 let steps = RecoveryStep::pipeline();
90 assert_eq!(steps.len(), 4);
91 assert_eq!(steps[0], RecoveryStep::LeaseExpired);
92 assert_eq!(steps[1], RecoveryStep::CheckpointReload);
93 assert_eq!(steps[2], RecoveryStep::Replay);
94 assert_eq!(steps[3], RecoveryStep::ReadyForDispatch);
95 }
96
97 #[test]
98 fn crash_recovery_pipeline_replay_context() {
99 let p = CrashRecoveryPipeline::new("attempt-1", "run-1");
100 let ctx = p.replay_context();
101 assert_eq!(ctx.attempt_id, "attempt-1");
102 assert_eq!(ctx.run_id, "run-1");
103 }
104}