Mountain/RunTime/Execute/
RunWithRetry.rs1#![allow(non_snake_case)]
2
3use std::sync::Arc;
8
9use CommonLibrary::{
10 Effect::{ActionEffect::ActionEffect, ApplicationRunTime::ApplicationRunTime as ApplicationRunTimeTrait},
11 Environment::Requires::Requires,
12 Error::CommonError::CommonError,
13};
14
15use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
16
17impl ApplicationRunTime {
18 pub async fn RunWithRetry<TCapabilityProvider, TError, TOutput>(
19 &self,
20 Effect:ActionEffect<Arc<TCapabilityProvider>, TError, TOutput>,
21 MaximumRetries:u32,
22 InitialDelay:std::time::Duration,
23 ) -> Result<TOutput, TError>
24 where
25 TCapabilityProvider: ?Sized + Send + Sync + 'static,
26 <Self as CommonLibrary::Environment::HasEnvironment::HasEnvironment>::EnvironmentType:
27 Requires<TCapabilityProvider>,
28 TError: From<CommonError> + Send + Sync + 'static + std::fmt::Display,
29 TOutput: Send + Sync + 'static, {
30 let mut RetryCount = 0;
31 let mut CurrentDelay = InitialDelay;
32
33 while RetryCount <= MaximumRetries {
34 match ApplicationRunTimeTrait::Run(self, Effect.clone()).await {
35 Ok(Result) => return Ok(Result),
36 Err(Error) => {
37 if RetryCount == MaximumRetries {
38 return Err(Error);
39 }
40 RetryCount += 1;
41 dev_log!(
42 "lifecycle",
43 "warn: [ApplicationRunTime] Effect execution failed (attempt {}): {}. Retrying in {:?}...",
44 RetryCount,
45 Error,
46 CurrentDelay
47 );
48 tokio::time::sleep(CurrentDelay).await;
49 CurrentDelay *= 2;
50 },
51 }
52 }
53
54 Err(
55 CommonError::Unknown { Description:format!("Effect execution failed after {} retries", MaximumRetries) }
56 .into(),
57 )
58 }
59}