use crate::{
model::{
artifacts::ArtifactChecksumRecord,
attempt_journal::{MutationOutcomeRecord, MutationReceiptRequest},
execution_workflow::ExecutionStagePredecessorRecord,
},
ops::persistence::{
AttemptJournalError, AttemptJournalGuard, ExecutionStageCheckpointError,
ExecutionStageGuard,
},
};
pub(super) fn record_applied<T, E: From<AttemptJournalError>>(
journal: &mut AttemptJournalGuard<'_>,
receipt: MutationReceiptRequest,
expected_attempt: u32,
expected_request: &str,
mismatch: E,
prepare: impl FnOnce() -> Result<T, E>,
) -> Result<T, E> {
if receipt.outcome != MutationOutcomeRecord::Applied
|| receipt.attempt != expected_attempt
|| receipt.request != expected_request
{
return Err(mismatch);
}
let result = prepare()?;
journal.record_mutation(receipt)?;
Ok(result)
}
pub(super) fn checkpoint_reply<R, E, X>(
stage: &ExecutionStageGuard<'_>,
reply: R,
settlement: Result<ArtifactChecksumRecord, E>,
reject: impl FnOnce(E, Box<R>) -> X,
) -> Result<(R, ExecutionStagePredecessorRecord), X>
where
E: From<ExecutionStageCheckpointError>,
{
match settlement.and_then(|evidence| stage.reconcile_checkpoint(evidence).map_err(E::from)) {
Ok(predecessor) => Ok((reply, predecessor)),
Err(source) => Err(reject(source, Box::new(reply))),
}
}