1use std::{
12 collections::{HashMap, HashSet},
13 sync::{Arc, Mutex},
14 time::{Duration, SystemTime},
15};
16
17use tauri::Emitter;
18use tokio::sync::RwLock;
19
20use crate::{
21 IPC::StatusReporter::{
22 ComprehensiveStatusReport::Struct as ComprehensiveStatusReport,
23 ConnectionStatus::Struct as ConnectionStatus,
24 HealthIssue::Struct as HealthIssue,
25 HealthIssueType::Enum as HealthIssueType,
26 HealthMonitor::Struct as HealthMonitor,
27 IPCStatusReport::Struct as IPCStatusReport,
28 MessageStats::Struct as MessageStats,
29 PerformanceMetrics::Struct as PerformanceMetrics,
30 ServiceInfo::Struct as ServiceInfo,
31 ServiceMetrics::Struct as ServiceMetrics,
32 ServiceRegistry::Struct as ServiceRegistry,
33 ServiceStatus::Enum as ServiceStatus,
34 SeverityLevel::Enum as SeverityLevel,
35 },
36 RunTime::ApplicationRunTime::ApplicationRunTime,
37 dev_log,
38};
39
40pub struct Struct {
41 pub(super) runtime:Arc<ApplicationRunTime>,
42
43 pub(super) ipc_server:Option<Arc<crate::IPC::TauriIPCServer_Old::TauriIPCServer>>,
44
45 pub(super) status_history:Arc<Mutex<Vec<IPCStatusReport>>>,
46
47 pub(super) start_time:SystemTime,
48
49 pub(super) error_count:Arc<Mutex<u32>>,
50
51 pub(super) performance_metrics:Arc<Mutex<PerformanceMetrics>>,
52
53 pub(super) health_monitor:Arc<Mutex<HealthMonitor>>,
54
55 pub(super) service_registry:Arc<RwLock<ServiceRegistry>>,
56
57 pub(super) discovered_services:Arc<RwLock<HashSet<String>>>,
58}
59
60impl Struct {
61 pub fn new(runtime:Arc<ApplicationRunTime>) -> Self {
62 dev_log!("lifecycle", "Creating IPC status reporter");
63
64 Self {
65 runtime,
66
67 ipc_server:None,
68
69 status_history:Arc::new(Mutex::new(Vec::new())),
70
71 start_time:SystemTime::now(),
72
73 error_count:Arc::new(Mutex::new(0)),
74
75 performance_metrics:Arc::new(Mutex::new(PerformanceMetrics {
76 messages_per_second:0.0,
77 average_latency_ms:0.0,
78 peak_latency_ms:0.0,
79 compression_ratio:1.0,
80 connection_pool_utilization:0.0,
81 memory_usage_mb:0.0,
82 cpu_usage_percent:0.0,
83 last_update:SystemTime::now()
84 .duration_since(SystemTime::UNIX_EPOCH)
85 .unwrap_or_default()
86 .as_millis() as u64,
87 })),
88
89 health_monitor:Arc::new(Mutex::new(HealthMonitor {
90 health_score:100.0,
91 last_health_check:SystemTime::now()
92 .duration_since(SystemTime::UNIX_EPOCH)
93 .unwrap_or_default()
94 .as_millis() as u64,
95 issues_detected:Vec::new(),
96 recovery_attempts:0,
97 })),
98
99 service_registry:Arc::new(RwLock::new(ServiceRegistry {
100 services:HashMap::new(),
101 last_discovery:SystemTime::now()
102 .duration_since(SystemTime::UNIX_EPOCH)
103 .unwrap_or_default()
104 .as_millis() as u64,
105 discovery_interval:30000,
106 })),
107
108 discovered_services:Arc::new(RwLock::new(HashSet::new())),
109 }
110 }
111
112 pub fn set_ipc_server(&mut self, ipc_server:Arc<crate::IPC::TauriIPCServer_Old::TauriIPCServer>) {
113 self.ipc_server = Some(ipc_server);
114 }
115
116 pub async fn generate_status_report(&self) -> Result<IPCStatusReport, String> {
117 dev_log!("lifecycle", "Generating IPC status report");
118
119 let ipc_server = self.ipc_server.as_ref().ok_or("IPC Server not set".to_string())?;
120
121 let connection_status = ConnectionStatus {
122 is_connected:ipc_server.get_connection_status()?,
123
124 last_heartbeat:SystemTime::now()
125 .duration_since(SystemTime::UNIX_EPOCH)
126 .unwrap_or_default()
127 .as_secs(),
128
129 connection_duration:SystemTime::now().duration_since(self.start_time).unwrap_or_default().as_secs(),
130 };
131
132 let message_queue_size = ipc_server.get_queue_size()?;
133
134 let active_listeners = vec!["configuration".to_string(), "file".to_string(), "storage".to_string()];
135
136 let recent_messages = vec![
137 MessageStats {
138 channel:"configuration".to_string(),
139
140 message_count:10,
141
142 last_message_time:SystemTime::now()
143 .duration_since(SystemTime::UNIX_EPOCH)
144 .unwrap_or_default()
145 .as_secs(),
146
147 average_processing_time_ms:5.0,
148 },
149 MessageStats {
150 channel:"file".to_string(),
151
152 message_count:5,
153
154 last_message_time:SystemTime::now()
155 .duration_since(SystemTime::UNIX_EPOCH)
156 .unwrap_or_default()
157 .as_secs() - 10,
158
159 average_processing_time_ms:15.0,
160 },
161 ];
162
163 let error_count = {
164 let guard = self
165 .error_count
166 .lock()
167 .map_err(|e| format!("Failed to get error count: {}", e))?;
168
169 *guard
170 };
171
172 let uptime_seconds = SystemTime::now().duration_since(self.start_time).unwrap_or_default().as_secs();
173
174 let report = IPCStatusReport {
175 timestamp:SystemTime::now()
176 .duration_since(SystemTime::UNIX_EPOCH)
177 .unwrap_or_default()
178 .as_millis() as u64,
179
180 connection_status,
181
182 message_queue_size,
183
184 active_listeners,
185
186 recent_messages,
187
188 error_count,
189
190 uptime_seconds,
191 };
192
193 {
194 let mut history = self
195 .status_history
196 .lock()
197 .map_err(|e| format!("Failed to access status history: {}", e))?;
198
199 history.push(report.clone());
200
201 if history.len() > 100 {
202 history.remove(0);
203 }
204 }
205
206 Ok(report)
207 }
208
209 pub async fn report_to_sky(&self) -> Result<(), String> {
210 dev_log!("lifecycle", "Reporting IPC status to Sky");
211
212 let report = self.generate_status_report().await?;
213
214 self.update_performance_metrics().await?;
215
216 self.perform_health_check().await?;
217
218 let performance_metrics = self.get_performance_metrics()?;
219
220 let health_status = self.get_health_status()?;
221
222 let comprehensive_report = ComprehensiveStatusReport {
223 basic_status:report.clone(),
224
225 performance_metrics:performance_metrics.clone(),
226
227 health_status:health_status.clone(),
228
229 timestamp:SystemTime::now()
230 .duration_since(SystemTime::UNIX_EPOCH)
231 .unwrap_or_default()
232 .as_millis() as u64,
233 };
234
235 if let Err(e) = self
236 .runtime
237 .Environment
238 .ApplicationHandle
239 .emit("ipc-status-report", &comprehensive_report)
240 {
241 dev_log!(
242 "lifecycle",
243 "error: [StatusReporter] Failed to emit status report to Sky: {}",
244 e
245 );
246
247 return Err(format!("Failed to emit status report: {}", e));
248 }
249
250 if let Err(e) = self
251 .runtime
252 .Environment
253 .ApplicationHandle
254 .emit("ipc-performance-metrics", &performance_metrics)
255 {
256 dev_log!("lifecycle", "error: [StatusReporter] Failed to emit performance metrics: {}", e);
257 }
258
259 if let Err(e) = self
260 .runtime
261 .Environment
262 .ApplicationHandle
263 .emit("ipc-health-status", &health_status)
264 {
265 dev_log!("lifecycle", "error: [StatusReporter] Failed to emit health status: {}", e);
266 }
267
268 dev_log!("lifecycle", "Comprehensive status report sent to Sky");
269
270 Ok(())
271 }
272
273 pub async fn start_periodic_reporting(&self, interval_seconds:u64) -> Result<(), String> {
274 dev_log!(
275 "lifecycle",
276 "[StatusReporter] Starting periodic status reporting (interval: {}s)",
277 interval_seconds
278 );
279
280 let reporter = self.clone_reporter();
281
282 tokio::spawn(async move {
283 let mut interval = tokio::time::interval(Duration::from_secs(interval_seconds));
284
285 loop {
286 interval.tick().await;
287
288 if let Err(e) = reporter.report_to_sky().await {
289 dev_log!("lifecycle", "error: [StatusReporter] Periodic reporting failed: {}", e);
290 }
291 }
292 });
293
294 Ok(())
295 }
296
297 pub fn record_error(&self) {
298 if let Ok(mut error_count) = self.error_count.lock() {
299 *error_count += 1;
300 }
301 }
302
303 pub fn get_status_history(&self) -> Result<Vec<IPCStatusReport>, String> {
304 let history = self
305 .status_history
306 .lock()
307 .map_err(|e| format!("Failed to access status history: {}", e))?;
308
309 Ok(history.clone())
310 }
311
312 pub fn get_start_time(&self) -> SystemTime { self.start_time }
313
314 pub async fn update_performance_metrics(&self) -> Result<(), String> {
315 let ipc_server = self.ipc_server.as_ref().ok_or("IPC Server not set".to_string())?;
316
317 let connection_stats = ipc_server.get_connection_stats().await.unwrap_or_default();
318
319 let messages_per_second = self.calculate_message_rate().await;
320
321 let average_latency_ms = self.calculate_average_latency().await;
322
323 let peak_latency_ms = self.calculate_peak_latency().await;
324
325 let compression_ratio = self.calculate_compression_ratio().await;
326
327 let connection_pool_utilization = self.calculate_pool_utilization(&connection_stats).await;
328
329 let memory_usage_mb = self.get_memory_usage().await;
330
331 let cpu_usage_percent = self.get_cpu_usage().await;
332
333 let last_update = SystemTime::now()
334 .duration_since(SystemTime::UNIX_EPOCH)
335 .unwrap_or_default()
336 .as_millis() as u64;
337
338 let mut metrics = self
339 .performance_metrics
340 .lock()
341 .map_err(|e| format!("Failed to access performance metrics: {}", e))?;
342
343 metrics.messages_per_second = messages_per_second;
344
345 metrics.average_latency_ms = average_latency_ms;
346
347 metrics.peak_latency_ms = peak_latency_ms;
348
349 metrics.compression_ratio = compression_ratio;
350
351 metrics.connection_pool_utilization = connection_pool_utilization;
352
353 metrics.memory_usage_mb = memory_usage_mb;
354
355 metrics.cpu_usage_percent = cpu_usage_percent;
356
357 metrics.last_update = last_update;
358
359 dev_log!(
360 "lifecycle",
361 "[StatusReporter] Performance metrics updated: {:.2} msg/s, {:.2}ms latency",
362 metrics.messages_per_second,
363 metrics.average_latency_ms
364 );
365
366 Ok(())
367 }
368
369 pub async fn perform_health_check(&self) -> Result<(), String> {
370 let mut health_monitor = self
371 .health_monitor
372 .lock()
373 .map_err(|e| format!("Failed to access health monitor: {}", e))?;
374
375 let mut health_score:f64 = 100.0;
376
377 let mut issues = Vec::new();
378
379 if let Some(ipc_server) = &self.ipc_server {
380 if !ipc_server.get_connection_status()? {
381 health_score -= 25.0;
382
383 issues.push(HealthIssue {
384 issue_type:HealthIssueType::ConnectionLoss,
385 severity:SeverityLevel::Critical,
386 description:"IPC connection lost".to_string(),
387 detected_at:SystemTime::now()
388 .duration_since(SystemTime::UNIX_EPOCH)
389 .unwrap_or_default()
390 .as_millis() as u64,
391 resolved_at:None,
392 });
393 }
394 }
395
396 if let Some(ipc_server) = &self.ipc_server {
397 let queue_size = ipc_server.get_queue_size()?;
398
399 if queue_size > 100 {
400 health_score -= 15.0;
401
402 issues.push(HealthIssue {
403 issue_type:HealthIssueType::QueueOverflow,
404 severity:SeverityLevel::High,
405 description:format!("Message queue overflow: {} messages", queue_size),
406 detected_at:SystemTime::now()
407 .duration_since(SystemTime::UNIX_EPOCH)
408 .unwrap_or_default()
409 .as_millis() as u64,
410 resolved_at:None,
411 });
412 }
413 }
414
415 let metrics = self
416 .performance_metrics
417 .lock()
418 .map_err(|e| format!("Failed to access performance metrics: {}", e))?;
419
420 if metrics.average_latency_ms > 100.0 {
421 health_score -= 20.0;
422
423 issues.push(HealthIssue {
424 issue_type:HealthIssueType::HighLatency,
425 severity:SeverityLevel::High,
426 description:format!("High latency detected: {:.2}ms", metrics.average_latency_ms),
427 detected_at:SystemTime::now()
428 .duration_since(SystemTime::UNIX_EPOCH)
429 .unwrap_or_default()
430 .as_millis() as u64,
431 resolved_at:None,
432 });
433 }
434
435 health_monitor.health_score = health_score.max(0.0);
436
437 health_monitor.issues_detected = issues;
438
439 health_monitor.last_health_check = SystemTime::now()
440 .duration_since(SystemTime::UNIX_EPOCH)
441 .unwrap_or_default()
442 .as_millis() as u64;
443
444 if health_score < 70.0 {
445 dev_log!(
446 "lifecycle",
447 "warn: [StatusReporter] Health check failed: score {:.1}%",
448 health_score
449 );
450
451 if let Err(e) = self
452 .runtime
453 .Environment
454 .ApplicationHandle
455 .emit("ipc-health-alert", &health_monitor.clone())
456 {
457 dev_log!("lifecycle", "error: [StatusReporter] Failed to emit health alert: {}", e);
458 }
459 }
460
461 Ok(())
462 }
463
464 async fn calculate_message_rate(&self) -> f64 {
465 let history = self.get_status_history().unwrap_or_default();
466
467 if history.len() < 2 {
468 return 0.0;
469 }
470
471 let recent_reports:Vec<&IPCStatusReport> = history.iter().rev().take(5).collect();
472
473 let total_messages:u32 = recent_reports
474 .iter()
475 .map(|report| report.recent_messages.iter().map(|m| m.message_count).sum::<u32>())
476 .sum();
477
478 let time_span = if recent_reports.len() > 1 {
479 let first_time = recent_reports.first().unwrap().timestamp;
480
481 let last_time = recent_reports.last().unwrap().timestamp;
482
483 (last_time - first_time) as f64 / 1000.0
484 } else {
485 1.0
486 };
487
488 total_messages as f64 / time_span.max(1.0)
489 }
490
491 async fn calculate_average_latency(&self) -> f64 {
492 let history = self.get_status_history().unwrap_or_default();
493
494 if history.is_empty() {
495 return 0.0;
496 }
497
498 let recent_reports:Vec<&IPCStatusReport> = history.iter().rev().take(10).collect();
499
500 let total_latency:f64 = recent_reports
501 .iter()
502 .flat_map(|report| &report.recent_messages)
503 .map(|msg| msg.average_processing_time_ms)
504 .sum();
505
506 let message_count = recent_reports.iter().flat_map(|report| &report.recent_messages).count();
507
508 total_latency / message_count.max(1) as f64
509 }
510
511 async fn calculate_peak_latency(&self) -> f64 {
512 let history = self.get_status_history().unwrap_or_default();
513
514 history
515 .iter()
516 .flat_map(|report| &report.recent_messages)
517 .map(|msg| msg.average_processing_time_ms)
518 .fold(0.0, f64::max)
519 }
520
521 async fn calculate_compression_ratio(&self) -> f64 { 2.5 }
522
523 async fn calculate_pool_utilization(&self, stats:&crate::IPC::TauriIPCServer_Old::ConnectionStats) -> f64 {
524 if stats.total_connections == 0 {
525 return 0.0;
526 }
527
528 stats.total_connections as f64 / stats.max_connections as f64
529 }
530
531 async fn get_memory_usage(&self) -> f64 { 50.0 }
532
533 async fn get_cpu_usage(&self) -> f64 { 15.0 }
534
535 pub async fn discover_services(&self) -> Result<Vec<ServiceInfo>, String> {
536 dev_log!("lifecycle", "Starting service discovery");
537
538 let mut registry = self.service_registry.write().await;
539
540 let mut discovered = self.discovered_services.write().await;
541
542 let mut services = Vec::new();
543
544 let core_services = vec![
545 ("EditorService", "1.0.0", ServiceStatus::Running),
546 ("ExtensionHostService", "1.0.0", ServiceStatus::Running),
547 ("ConfigurationService", "1.0.0", ServiceStatus::Running),
548 ("FileService", "1.0.0", ServiceStatus::Running),
549 ("StorageService", "1.0.0", ServiceStatus::Running),
550 ];
551
552 for (name, version, status) in core_services {
553 let service_info = ServiceInfo {
554 name:name.to_string(),
555
556 version:version.to_string(),
557
558 status:status.clone(),
559
560 last_heartbeat:SystemTime::now()
561 .duration_since(SystemTime::UNIX_EPOCH)
562 .unwrap_or_default()
563 .as_millis() as u64,
564
565 uptime:SystemTime::now().duration_since(self.start_time).unwrap_or_default().as_secs(),
566
567 dependencies:self.get_service_dependencies(name),
568
569 metrics:ServiceMetrics {
570 response_time:self.calculate_service_response_time(name).await,
571
572 error_rate:self.calculate_service_error_rate(name).await,
573
574 throughput:self.calculate_service_throughput(name).await,
575
576 memory_usage:self.get_service_memory_usage(name).await,
577
578 cpu_usage:self.get_service_cpu_usage(name).await,
579
580 last_updated:SystemTime::now()
581 .duration_since(SystemTime::UNIX_EPOCH)
582 .unwrap_or_default()
583 .as_millis() as u64,
584 },
585
586 endpoint:Some(format!("localhost:{}", 50050 + services.len() as u16)),
587
588 port:Some(50050 + services.len() as u16),
589 };
590
591 registry.services.insert(name.to_string(), service_info.clone());
592
593 discovered.insert(name.to_string());
594
595 services.push(service_info);
596 }
597
598 registry.last_discovery = SystemTime::now()
599 .duration_since(SystemTime::UNIX_EPOCH)
600 .unwrap_or_default()
601 .as_millis() as u64;
602
603 dev_log!(
604 "lifecycle",
605 "[StatusReporter] Service discovery completed: {} services found",
606 services.len()
607 );
608
609 if let Err(e) = self
610 .runtime
611 .Environment
612 .ApplicationHandle
613 .emit("mountain_service_discovery", &services)
614 {
615 dev_log!(
616 "lifecycle",
617 "error: [StatusReporter] Failed to emit service discovery event: {}",
618 e
619 );
620 }
621
622 Ok(services)
623 }
624
625 fn get_service_dependencies(&self, service_name:&str) -> Vec<String> {
626 match service_name {
627 "ExtensionHostService" => vec!["ConfigurationService".to_string()],
628
629 "FileService" => vec!["StorageService".to_string()],
630
631 "StorageService" => vec!["ConfigurationService".to_string()],
632
633 _ => Vec::new(),
634 }
635 }
636
637 async fn calculate_service_response_time(&self, service_name:&str) -> f64 {
638 match service_name {
639 "EditorService" => 5.0,
640
641 "ExtensionHostService" => 15.0,
642
643 "ConfigurationService" => 2.0,
644
645 "FileService" => 8.0,
646
647 "StorageService" => 3.0,
648
649 _ => 10.0,
650 }
651 }
652
653 async fn calculate_service_error_rate(&self, service_name:&str) -> f64 {
654 match service_name {
655 "EditorService" => 0.1,
656
657 "ExtensionHostService" => 2.5,
658
659 "ConfigurationService" => 0.5,
660
661 "FileService" => 1.2,
662
663 "StorageService" => 0.8,
664
665 _ => 5.0,
666 }
667 }
668
669 async fn calculate_service_throughput(&self, service_name:&str) -> f64 {
670 match service_name {
671 "EditorService" => 1000.0,
672
673 "ExtensionHostService" => 500.0,
674
675 "ConfigurationService" => 2000.0,
676
677 "FileService" => 800.0,
678
679 "StorageService" => 1500.0,
680
681 _ => 100.0,
682 }
683 }
684
685 async fn get_service_memory_usage(&self, service_name:&str) -> f64 {
686 match service_name {
687 "EditorService" => 256.0,
688
689 "ExtensionHostService" => 512.0,
690
691 "ConfigurationService" => 128.0,
692
693 "FileService" => 192.0,
694
695 "StorageService" => 64.0,
696
697 _ => 100.0,
698 }
699 }
700
701 async fn get_service_cpu_usage(&self, service_name:&str) -> f64 {
702 match service_name {
703 "EditorService" => 15.0,
704
705 "ExtensionHostService" => 25.0,
706
707 "ConfigurationService" => 5.0,
708
709 "FileService" => 10.0,
710
711 "StorageService" => 8.0,
712
713 _ => 20.0,
714 }
715 }
716
717 pub async fn start_periodic_discovery(&self) -> Result<(), String> {
718 dev_log!("lifecycle", "Starting periodic service discovery");
719
720 let registry = self.service_registry.read().await;
721
722 let interval = registry.discovery_interval;
723
724 drop(registry);
725
726 let reporter = self.clone_reporter();
727
728 tokio::spawn(async move {
729 let mut interval = tokio::time::interval(Duration::from_millis(interval));
730
731 loop {
732 interval.tick().await;
733
734 if let Err(e) = reporter.discover_services().await {
735 dev_log!("lifecycle", "error: [StatusReporter] Periodic service discovery failed: {}", e);
736 }
737 }
738 });
739
740 Ok(())
741 }
742
743 pub async fn get_service_registry(&self) -> Result<ServiceRegistry, String> {
744 let registry = self.service_registry.read().await;
745
746 Ok(registry.clone())
747 }
748
749 pub async fn get_service_info(&self, service_name:&str) -> Result<Option<ServiceInfo>, String> {
750 let registry = self.service_registry.read().await;
751
752 Ok(registry.services.get(service_name).cloned())
753 }
754
755 pub async fn attempt_recovery(&self) -> Result<(), String> {
756 let mut health_monitor = self
757 .health_monitor
758 .lock()
759 .map_err(|e| format!("Failed to access health monitor: {}", e))?;
760
761 health_monitor.recovery_attempts += 1;
762
763 if let Some(ipc_server) = &self.ipc_server {
764 if let Err(e) = ipc_server.dispose() {
765 return Err(format!("Failed to dispose IPC server: {}", e));
766 }
767
768 if let Err(e) = ipc_server.initialize().await {
769 return Err(format!("Failed to reinitialize IPC server: {}", e));
770 }
771 }
772
773 if let Ok(mut error_count) = self.error_count.lock() {
774 *error_count = 0;
775 }
776
777 dev_log!(
778 "lifecycle",
779 "[StatusReporter] Recovery attempt {} completed",
780 health_monitor.recovery_attempts
781 );
782
783 Ok(())
784 }
785
786 pub fn get_performance_metrics(&self) -> Result<PerformanceMetrics, String> {
787 let metrics = self
788 .performance_metrics
789 .lock()
790 .map_err(|e| format!("Failed to access performance metrics: {}", e))?;
791
792 Ok(metrics.clone())
793 }
794
795 pub fn get_health_status(&self) -> Result<HealthMonitor, String> {
796 let health_monitor = self
797 .health_monitor
798 .lock()
799 .map_err(|e| format!("Failed to access health monitor: {}", e))?;
800
801 Ok(health_monitor.clone())
802 }
803
804 pub(super) fn clone_reporter(&self) -> Struct {
805 Struct {
806 runtime:self.runtime.clone(),
807
808 ipc_server:self.ipc_server.clone(),
809
810 status_history:self.status_history.clone(),
811
812 start_time:self.start_time,
813
814 error_count:self.error_count.clone(),
815
816 performance_metrics:self.performance_metrics.clone(),
817
818 health_monitor:self.health_monitor.clone(),
819
820 service_registry:self.service_registry.clone(),
821
822 discovered_services:self.discovered_services.clone(),
823 }
824 }
825}