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
21 Effect:ActionEffect<Arc<TCapabilityProvider>, TError, TOutput>,
22
23 MaximumRetries:u32,
24
25 InitialDelay:std::time::Duration,
26 ) -> Result<TOutput, TError>
27 where
28 TCapabilityProvider: ?Sized + Send + Sync + 'static,
29 <Self as CommonLibrary::Environment::HasEnvironment::HasEnvironment>::EnvironmentType:
30 Requires<TCapabilityProvider>,
31 TError: From<CommonError> + Send + Sync + 'static + std::fmt::Display,
32 TOutput: Send + Sync + 'static, {
33 let mut RetryCount = 0;
34
35 let mut CurrentDelay = InitialDelay;
36
37 while RetryCount <= MaximumRetries {
38 match ApplicationRunTimeTrait::Run(self, Effect.clone()).await {
39 Ok(Result) => return Ok(Result),
40
41 Err(Error) => {
42 if RetryCount == MaximumRetries {
43 return Err(Error);
44 }
45
46 RetryCount += 1;
47
48 dev_log!(
49 "lifecycle",
50 "warn: [ApplicationRunTime] Effect execution failed (attempt {}): {}. Retrying in {:?}...",
51 RetryCount,
52 Error,
53 CurrentDelay
54 );
55
56 tokio::time::sleep(CurrentDelay).await;
57
58 CurrentDelay *= 2;
59 },
60 }
61 }
62
63 Err(
64 CommonError::Unknown { Description:format!("Effect execution failed after {} retries", MaximumRetries) }
65 .into(),
66 )
67 }
68}