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