Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/AdvancedFeatures/
Features.rs

1//! `AdvancedFeatures` aggregator - holds the runtime handle,
2//! cumulative `PerformanceStats::Struct`, the realtime
3//! collaboration-session map, and the
4//! `MessageCache::Struct`. Spawns three monitor tasks
5//! (`monitor_performance`, `cleanup_cache`,
6//! `monitor_collaboration_sessions`) on `start_monitoring`.
7//! The 12-method impl is kept in one file - tightly-coupled
8//! cluster.
9
10use std::{
11	collections::HashMap,
12	sync::{Arc, Mutex},
13	time::{Duration, SystemTime},
14};
15
16use tauri::Emitter;
17use tokio::time::interval;
18
19use crate::{
20	IPC::AdvancedFeatures::{
21		CachedMessage::Struct as CachedMessage,
22		CollaborationPermissions::Struct as CollaborationPermissions,
23		CollaborationSession::Struct as CollaborationSession,
24		MessageCache::Struct as MessageCache,
25		PerformanceStats::Struct as PerformanceStats,
26	},
27	RunTime::ApplicationRunTime::ApplicationRunTime,
28	dev_log,
29};
30
31#[derive(Clone)]
32pub struct Struct {
33	pub(super) runtime:Arc<ApplicationRunTime>,
34
35	pub(super) performance_stats:Arc<Mutex<PerformanceStats>>,
36
37	pub(super) collaboration_sessions:Arc<Mutex<HashMap<String, CollaborationSession>>>,
38
39	pub(super) message_cache:Arc<Mutex<MessageCache>>,
40}
41
42impl Struct {
43	pub fn new(runtime:Arc<ApplicationRunTime>) -> Self {
44		dev_log!("lifecycle", "Initializing advanced IPC features");
45
46		Self {
47			runtime,
48
49			performance_stats:Arc::new(Mutex::new(PerformanceStats {
50				total_messages_sent:0,
51				total_messages_received:0,
52				average_processing_time_ms:0.0,
53				peak_message_rate:0,
54				error_count:0,
55				last_update:SystemTime::now()
56					.duration_since(SystemTime::UNIX_EPOCH)
57					.unwrap_or_default()
58					.as_secs(),
59				connection_uptime:0,
60			})),
61
62			collaboration_sessions:Arc::new(Mutex::new(HashMap::new())),
63
64			message_cache:Arc::new(Mutex::new(MessageCache {
65				cached_messages:HashMap::new(),
66				cache_hits:0,
67				cache_misses:0,
68				cache_size:0,
69			})),
70		}
71	}
72
73	pub async fn start_monitoring(&self) -> Result<(), String> {
74		dev_log!("lifecycle", "Starting advanced monitoring");
75
76		let features1 = self.clone_features();
77
78		let features2 = self.clone_features();
79
80		let features3 = self.clone_features();
81
82		tokio::spawn(async move {
83			features1.monitor_performance().await;
84		});
85
86		tokio::spawn(async move {
87			features2.cleanup_cache().await;
88		});
89
90		tokio::spawn(async move {
91			features3.monitor_collaboration_sessions().await;
92		});
93
94		Ok(())
95	}
96
97	async fn monitor_performance(&self) {
98		let mut interval = interval(Duration::from_secs(10));
99
100		loop {
101			interval.tick().await;
102
103			let stats = self.calculate_performance_stats().await;
104
105			if let Err(e) = self.runtime.Environment.ApplicationHandle.emit("ipc-performance-stats", &stats) {
106				dev_log!("ipc", "error: [AdvancedFeatures] Failed to emit performance stats: {}", e);
107			}
108
109			dev_log!("lifecycle", "Performance stats updated");
110		}
111	}
112
113	async fn calculate_performance_stats(&self) -> PerformanceStats {
114		let mut stats = self.performance_stats.lock().unwrap();
115
116		stats.connection_uptime = SystemTime::now()
117			.duration_since(SystemTime::UNIX_EPOCH)
118			.unwrap_or_default()
119			.as_secs()
120			- stats.last_update;
121
122		stats.last_update = SystemTime::now()
123			.duration_since(SystemTime::UNIX_EPOCH)
124			.unwrap_or_default()
125			.as_secs();
126
127		stats.clone()
128	}
129
130	async fn cleanup_cache(&self) {
131		let mut interval = interval(Duration::from_secs(60));
132
133		loop {
134			interval.tick().await;
135
136			let current_time = SystemTime::now()
137				.duration_since(SystemTime::UNIX_EPOCH)
138				.unwrap_or_default()
139				.as_secs();
140
141			let mut cache = self.message_cache.lock().unwrap();
142
143			cache
144				.cached_messages
145				.retain(|_, cached_message| current_time < cached_message.timestamp + cached_message.ttl);
146
147			cache.cache_size = cache.cached_messages.len();
148
149			dev_log!("lifecycle", "Cache cleaned, {} entries remaining", cache.cache_size);
150		}
151	}
152
153	async fn monitor_collaboration_sessions(&self) {
154		let mut interval = interval(Duration::from_secs(30));
155
156		loop {
157			interval.tick().await;
158
159			let current_time = SystemTime::now()
160				.duration_since(SystemTime::UNIX_EPOCH)
161				.unwrap_or_default()
162				.as_secs();
163
164			let mut sessions = self.collaboration_sessions.lock().unwrap();
165
166			sessions.retain(|_, session| current_time - session.last_activity < 300);
167
168			let active_sessions:Vec<CollaborationSession> = sessions.values().cloned().collect();
169
170			if let Err(e) = self
171				.runtime
172				.Environment
173				.ApplicationHandle
174				.emit("collaboration-sessions-update", &active_sessions)
175			{
176				dev_log!("ipc", "error: [AdvancedFeatures] Failed to emit collaboration sessions: {}", e);
177			}
178
179			dev_log!("lifecycle", "Collaboration sessions monitored, {} active", sessions.len());
180		}
181	}
182
183	pub async fn cache_message(&self, message_id:String, data:serde_json::Value, ttl:u64) -> Result<(), String> {
184		let mut cache = self
185			.message_cache
186			.lock()
187			.map_err(|e| format!("Failed to access message cache: {}", e))?;
188
189		let cached_message = CachedMessage {
190			data,
191
192			timestamp:SystemTime::now()
193				.duration_since(SystemTime::UNIX_EPOCH)
194				.unwrap_or_default()
195				.as_secs(),
196
197			ttl,
198		};
199
200		cache.cached_messages.insert(message_id.clone(), cached_message);
201
202		cache.cache_size = cache.cached_messages.len();
203
204		dev_log!("lifecycle", "Message cached: {}, TTL: {}s", message_id, ttl);
205
206		Ok(())
207	}
208
209	pub async fn get_cached_message(&self, message_id:&str) -> Option<serde_json::Value> {
210		let mut cache = self.message_cache.lock().unwrap();
211
212		let result = cache
213			.cached_messages
214			.get(message_id)
215			.map(|cached_message| cached_message.data.clone());
216
217		if result.is_some() {
218			cache.cache_hits += 1;
219		} else {
220			cache.cache_misses += 1;
221		}
222
223		result
224	}
225
226	pub async fn create_collaboration_session(
227		&self,
228
229		session_id:String,
230
231		permissions:CollaborationPermissions,
232	) -> Result<(), String> {
233		let mut sessions = self
234			.collaboration_sessions
235			.lock()
236			.map_err(|e| format!("Failed to access collaboration sessions: {}", e))?;
237
238		let session = CollaborationSession {
239			session_id:session_id.clone(),
240
241			participants:Vec::new(),
242
243			active_documents:Vec::new(),
244
245			last_activity:SystemTime::now()
246				.duration_since(SystemTime::UNIX_EPOCH)
247				.unwrap_or_default()
248				.as_secs(),
249
250			permissions,
251		};
252
253		sessions.insert(session_id, session);
254
255		dev_log!("lifecycle", "Collaboration session created");
256
257		Ok(())
258	}
259
260	pub async fn add_participant(&self, session_id:&str, participant:String) -> Result<(), String> {
261		let mut sessions = self
262			.collaboration_sessions
263			.lock()
264			.map_err(|e| format!("Failed to access collaboration sessions: {}", e))?;
265
266		if let Some(session) = sessions.get_mut(session_id) {
267			if !session.participants.contains(&participant) {
268				session.participants.push(participant);
269
270				session.last_activity = SystemTime::now()
271					.duration_since(SystemTime::UNIX_EPOCH)
272					.unwrap_or_default()
273					.as_secs();
274
275				dev_log!("lifecycle", "Participant added to session: {}", session_id);
276			}
277		} else {
278			return Err(format!("Session not found: {}", session_id));
279		}
280
281		Ok(())
282	}
283
284	pub async fn record_message_statistics(&self, sent:bool, processing_time_ms:u64) {
285		let mut stats = self.performance_stats.lock().unwrap();
286
287		if sent {
288			stats.total_messages_sent += 1;
289		} else {
290			stats.total_messages_received += 1;
291		}
292
293		let total_messages = stats.total_messages_sent + stats.total_messages_received;
294
295		stats.average_processing_time_ms = (stats.average_processing_time_ms * (total_messages - 1) as f64
296			+ processing_time_ms as f64)
297			/ total_messages as f64;
298	}
299
300	pub async fn record_error(&self) {
301		let mut stats = self.performance_stats.lock().unwrap();
302
303		stats.error_count += 1;
304	}
305
306	pub async fn get_performance_stats(&self) -> Result<PerformanceStats, String> {
307		Ok(self.calculate_performance_stats().await)
308	}
309
310	pub async fn get_cache_stats(&self) -> Result<MessageCache, String> {
311		let cache = self.message_cache.lock().unwrap();
312
313		Ok(cache.clone())
314	}
315
316	pub async fn get_collaboration_sessions(&self) -> Vec<CollaborationSession> {
317		let sessions = self.collaboration_sessions.lock().unwrap();
318
319		sessions.values().cloned().collect()
320	}
321
322	pub(super) fn clone_features(&self) -> Self {
323		Self {
324			runtime:self.runtime.clone(),
325
326			performance_stats:self.performance_stats.clone(),
327
328			collaboration_sessions:self.collaboration_sessions.clone(),
329
330			message_cache:self.message_cache.clone(),
331		}
332	}
333}