168 lines
5.9 KiB
Rust
168 lines
5.9 KiB
Rust
//! 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<config::Config>,
|
|
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<cache::FileCache>,
|
|
pub metrics: Arc<utils::metrics::Metrics>,
|
|
pub analytics: Arc<analytics::AnalyticsEngine>,
|
|
pub audio_processor: Arc<audio::processing::AudioProcessor>,
|
|
pub adaptive_streaming: Arc<streaming::adaptive::AdaptiveStreamingManager>,
|
|
pub health_monitor: Arc<health::HealthMonitor>,
|
|
pub auth_manager: Arc<auth::AuthManager>,
|
|
pub compression_engine: Arc<audio::compression::CompressionEngine>,
|
|
pub notification_service: Arc<notifications::NotificationService>,
|
|
pub websocket_manager: Arc<streaming::websocket::WebSocketManager>,
|
|
pub event_bus: Option<Arc<event_bus::RabbitMQEventBus>>, // Add RabbitMQEventBus, wrapped in Arc for Clone trait
|
|
pub transcoding_engine: Arc<transcoding::TranscodingEngine>, // Transcoding engine for audio encoding
|
|
pub sync_engine: Arc<SyncEngine>,
|
|
pub stream_manager: Arc<StreamManager>,
|
|
}
|
|
|
|
impl AppState {
|
|
pub async fn new(config: config::Config) -> Result<Self, Box<dyn std::error::Error>> {
|
|
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);
|
|
}
|
|
}
|