Skip to main content

Mountain/RunTime/Shutdown/
DisposeTerminalsSafely.rs

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