ic_backup/ops/persistence/execution_workflow/progress/
mod.rs1use super::{
4 ArtifactChecksumRecord, BINDING_FILE, BackupLayoutGuard, ExecutionProgressPersistenceError,
5 ExecutionStageBindingRecord, ExecutionWorkflowPersistenceError, MAX_EXECUTION_STAGE_BYTES,
6 ancestry::{acquire_stage, read_admitted_binding},
7 read_execution_progress, read_execution_stage_occupancy, read_execution_workflow, read_json,
8};
9use crate::view::execution_workflow::{
10 ExecutionStageProgressState, ExecutionStageProgressView, ExecutionWorkflowProgressView,
11};
12use thiserror::Error;
13
14pub fn read_execution_workflow_progress(
25 layout: &BackupLayoutGuard,
26 expected: &ArtifactChecksumRecord,
27) -> Result<ExecutionWorkflowProgressView, ExecutionWorkflowProgressError> {
28 let workflow = read_execution_workflow(layout, expected)?;
29 let occupied = read_execution_stage_occupancy(layout, expected)?;
30 let mut stages = Vec::with_capacity(workflow.stages().len());
31 for node in workflow.allocation().graph().ordered_nodes() {
32 let sequence = node.operation_sequence();
33 let state = if occupied.contains(&sequence) {
34 let child = acquire_stage(layout, sequence)?;
35 let binding: ExecutionStageBindingRecord =
36 read_json(&child.root().join(BINDING_FILE), MAX_EXECUTION_STAGE_BYTES)
37 .map_err(ExecutionWorkflowPersistenceError::from)?;
38 let (binding, plan) =
39 read_admitted_binding(layout, &child, &workflow, sequence, &binding.digest())?;
40 let progress = read_execution_progress(&child, &plan.digest())?;
41 read_admitted_binding(layout, &child, &workflow, sequence, &binding.digest())?;
42 ExecutionStageProgressState::Prepared {
43 binding: binding.digest(),
44 progress: Box::new(progress),
45 }
46 } else {
47 ExecutionStageProgressState::Unprepared
48 };
49 stages.push(ExecutionStageProgressView {
50 stage_sequence: sequence,
51 state,
52 });
53 }
54 if read_execution_stage_occupancy(layout, expected)? != occupied {
55 return Err(ExecutionWorkflowPersistenceError::DigestMismatch.into());
56 }
57 Ok(ExecutionWorkflowProgressView {
58 workflow: expected.clone(),
59 stages,
60 })
61}
62
63#[derive(Debug, Error)]
65pub enum ExecutionWorkflowProgressError {
66 #[error(transparent)]
68 Stage(#[from] ExecutionWorkflowPersistenceError),
69 #[error(transparent)]
71 Journals(#[from] ExecutionProgressPersistenceError),
72}