Skip to main content

Mountain/RunTime/Shutdown/
DisposeTerminalsSafely.rs

1
2//! Dispose every active PTY through `TerminalProvider::DisposeTerminal`.
3//! Errors per terminal are collected; the loop never aborts early.
4
5use std::sync::Arc;
6
7use CommonLibrary::{
8	Environment::Requires::Requires,
9	Error::CommonError::CommonError,
10	Terminal::TerminalProvider::TerminalProvider as TerminalProviderTrait,
11};
12
13use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
14
15impl ApplicationRunTime {
16	pub async fn DisposeTerminalsSafely(&self) -> Result<(), CommonError> {
17		let TerminalProvider:Arc<dyn TerminalProviderTrait> = self.Environment.Require();
18
19		let TerminalIdentifiers:Vec<u64> = {
20			let TerminalsGuard = self
21				.Environment
22				.ApplicationState
23				.Feature
24				.Terminals
25				.ActiveTerminals
26				.lock()
27				.map_err(|E| CommonError::StateLockPoisoned { Context:E.to_string() })?;
28
29			TerminalsGuard.keys().cloned().collect()
30		};
31
32		let mut DisposalErrors:Vec<String> = Vec::new();
33
34		for Identifier in TerminalIdentifiers {
35			match TerminalProvider.DisposeTerminal(Identifier).await {
36				Ok(()) => {
37					dev_log!(
38						"lifecycle",
39						"[ApplicationRunTime] Terminal {} disposed successfully",
40						Identifier
41					)
42				},
43
44				Err(Error) => {
45					DisposalErrors.push(format!("Terminal {}: {}", Identifier, Error));
46
47					dev_log!(
48						"lifecycle",
49						"warn: [ApplicationRunTime] Failed to dispose terminal {}: {}",
50						Identifier,
51						Error
52					);
53				},
54			}
55		}
56
57		if !DisposalErrors.is_empty() {
58			Err(CommonError::Unknown {
59				Description:format!(
60					"Terminal disposal completed with {} errors: {:?}",
61					DisposalErrors.len(),
62					DisposalErrors
63				),
64			})
65		} else {
66			Ok(())
67		}
68	}
69}