//! Stream Server pour Veza //! //! Serveur de streaming audio temps réel avec WebRTC pub mod analytics; pub mod audio; pub mod auth; pub mod cache; pub mod codecs; pub mod config; pub mod core; pub mod database; pub mod error; pub mod event_bus; pub mod health; pub mod middleware; pub mod monitoring; pub mod notifications; pub mod routes; pub mod streaming; pub mod structured_logging; pub mod transcoding; // NEW: Phase 3 Transcoding Engine pub mod utils; // ORIGIN Architecture: Event-driven via RabbitMQ use std::collections::HashMap; use std::sync::Arc; use sqlx::PgPool; use tokio::sync::RwLock; use parking_lot::RwLock as PlRwLock; use crate::core::sync::{SyncEngine, TimeServer, DriftCompensator, SyncConfig as CoreSyncConfig}; use crate::core::stream::{StreamManager, StreamConfig as CoreStreamConfig}; use crate::streaming::websocket_transport::WebSocketSyncTransport; /// État global de l'application /// Cette structure contient tous les services et composants nécessaires au serveur #[derive(Clone)] pub struct AppState { pub config: Arc, pub pool: PgPool, // Ces champs sont initialisés dans main.rs via create_app_state() // Utilisation de pub pour permettre l'accès depuis main.rs et les routes pub cache: Arc, pub metrics: Arc, pub analytics: Arc, pub audio_processor: Arc, pub adaptive_streaming: Arc, pub health_monitor: Arc, pub auth_manager: Arc, pub compression_engine: Arc, pub notification_service: Arc, pub websocket_manager: Arc, pub event_bus: Option>, // Add RabbitMQEventBus, wrapped in Arc for Clone trait pub transcoding_engine: Arc, // Transcoding engine for audio encoding pub sync_engine: Arc, pub stream_manager: Arc, } impl AppState { pub async fn new(config: config::Config) -> Result> { let config_arc = Arc::new(config.clone()); // Create database pool let pool = database::create_pool_from_config(&config.database).await?; // Run migrations if enabled if config.database.migrate_on_start { tracing::info!("🔄 Exécution des migrations de base de données..."); sqlx::migrate!("./migrations") .run(&pool) .await .map_err(|e| format!("Migration failed: {}", e))?; tracing::info!("✅ Migrations terminées avec succès"); } // Cache needs max_size_mb as usize let cache = Arc::new(cache::FileCache::new(config.cache.max_size_mb as usize)); // Metrics needs config let metrics = Arc::new(utils::metrics::Metrics::new(config_arc.clone())); // AnalyticsEngine uses the shared pool let analytics = Arc::new( analytics::AnalyticsEngine::new(pool.clone(), config_arc.clone()).await?, ); let audio_processor = Arc::new(audio::processing::AudioProcessor::new(config_arc.clone())); let compression_engine = Arc::new(audio::compression::CompressionEngine::new( config_arc.clone(), )); // HealthMonitor needs config and analytics for db check let health_monitor = Arc::new(health::HealthMonitor::new(config_arc.clone(), analytics.clone())); // AuthManager::new returns Result let auth_manager = Arc::new(auth::AuthManager::new(config_arc.clone())?); let notification_service = Arc::new(notifications::NotificationService::new(config_arc.clone())); // WebSocketManager::new takes no arguments let websocket_manager = Arc::new(streaming::websocket::WebSocketManager::new()); // Adaptive streaming manager let adaptive_streaming = Arc::new(streaming::adaptive::AdaptiveStreamingManager::new( config_arc.clone(), )); // Transcoding engine let worker_count = num_cpus::get(); let transcoding_engine = Arc::new(transcoding::TranscodingEngine::new(worker_count)); // Démarrer les workers transcoding_engine.start(); // SyncEngine initialization let time_server = Arc::new(TimeServer::new(vec![]).await.map_err(|e| format!("Failed to init TimeServer: {}", e))?); let drift_compensator = Arc::new(DriftCompensator::new()); let sync_config = Arc::new(PlRwLock::new(CoreSyncConfig::default())); let sync_transport = Arc::new(WebSocketSyncTransport::new(websocket_manager.clone())); let sync_engine = Arc::new(SyncEngine::new( time_server, drift_compensator, sync_config, Some(sync_transport), // Now using real transport! )); // StreamManager initialization let stream_manager = Arc::new(StreamManager::new( CoreStreamConfig::default(), pool.clone(), sync_engine.clone(), ).await?); // Start the sync loop stream_manager.start_sync_loop().await; Ok(Self { config: config_arc, pool, cache, metrics, analytics, audio_processor, adaptive_streaming, health_monitor, auth_manager, compression_engine, notification_service, websocket_manager, event_bus: None, // Initialisé à None, sera assigné dans main.rs transcoding_engine, sync_engine, stream_manager, }) } } #[cfg(test)] mod tests { use super::*; #[test] fn test_app_state_structure() { // Just verify struct exists assert!(true); } }