Mountain/RunTime/Shutdown/
ShutdownCocoonWithRetry.rs1#![allow(non_snake_case)]
2
3use std::sync::Arc;
10
11use CommonLibrary::{Environment::Requires::Requires, Error::CommonError::CommonError, IPC::IPCProvider::IPCProvider};
12
13use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
14
15impl ApplicationRunTime {
16 pub async fn ShutdownCocoonWithRetry(&self) -> Result<(), CommonError> {
17 let IPCProvider:Arc<dyn IPCProvider> = self.Environment.Require();
18
19 let MaximumAttempts = 3;
20 let mut Attempts = 0;
21 let mut GracefulOk = false;
22 let mut LastError:Option<CommonError> = None;
23
24 while Attempts < MaximumAttempts {
25 match IPCProvider
26 .SendNotificationToSideCar("cocoon-main".to_string(), "$shutdown".to_string(), serde_json::Value::Null)
27 .await
28 {
29 Ok(()) => {
30 tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
31 GracefulOk = true;
32 break;
33 },
34 Err(Error) => {
35 Attempts += 1;
36 LastError = Some(Error.clone());
37 if Attempts < MaximumAttempts {
38 dev_log!(
39 "lifecycle",
40 "warn: [ApplicationRunTime] Cocoon shutdown attempt {} failed: {}. Retrying...",
41 Attempts,
42 Error
43 );
44 tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
45 }
46 },
47 }
48 }
49
50 crate::Vine::Client::MarkShutdown::Fn();
55
56 crate::ProcessManagement::CocoonManagement::HardKillCocoon().await;
59
60 if GracefulOk {
61 Ok(())
62 } else {
63 Err(LastError.unwrap_or_else(|| {
64 CommonError::Unknown { Description:"Failed to shutdown Cocoon after maximum retries".to_string() }
65 }))
66 }
67 }
68}