# Améliorations de la séquence de démarrage de sdk_relay ## Problème actuel - Le serveur WebSocket ne démarre qu'après le scan complet des blocs - Les services dépendants (ihm_client, etc.) ne peuvent pas se connecter pendant le scan - Le scan peut prendre plusieurs minutes et bloquer complètement le service ## Solutions proposées ### 1. Démarrage immédiat des serveurs (Recommandé) ```rust // Dans main.rs, démarrer les serveurs AVANT le scan async fn main() -> Result<(), Box> { // ... configuration ... // DÉMARRER LES SERVEURS IMMÉDIATEMENT let try_socket = TcpListener::bind(config.ws_url).await?; let listener = try_socket; // Démarrer le serveur de santé immédiatement tokio::spawn(start_health_server(8091)); // Démarrer le serveur WebSocket dans une tâche séparée let ws_handle = tokio::spawn(async move { while let Ok((stream, addr)) = listener.accept().await { tokio::spawn(handle_connection(stream, addr, our_sp_address)); } }); // FAIRE LE SCAN EN ARRIÈRE-PLAN tokio::spawn(async move { if let Err(e) = scan_blocks(current_tip - last_scan, &config.blindbit_url).await { eprintln!("Scan error: {}", e); } }); // Attendre que le serveur WebSocket soit prêt ws_handle.await?; Ok(()) } ``` ### 2. Mode "dégradé" pendant le scan ```rust // Ajouter un état de service enum ServiceState { Starting, Scanning, Ready, Error, } // Le serveur WebSocket accepte les connexions mais répond avec un état async fn handle_connection(stream: TcpStream, addr: SocketAddr, state: Arc>) { let current_state = state.lock().await; match *current_state { ServiceState::Scanning => { // Répondre avec un message indiquant que le service est en cours de scan send_message(stream, json!({ "status": "scanning", "message": "Service is scanning blocks, please wait..." })).await; }, ServiceState::Ready => { // Traitement normal des messages handle_normal_connection(stream).await; }, _ => { // Répondre avec une erreur send_error(stream, "Service not ready").await; } } } ``` ### 3. Scan incrémental en arrière-plan ```rust // Modifier le scan pour qu'il soit non-bloquant async fn start_background_scan(start_block: u32, end_block: u32, blindbit_url: &str) { let mut current = start_block; while current <= end_block { match scan_single_block(current, blindbit_url).await { Ok(_) => { current += 1; // Mettre à jour le last_scan dans le wallet update_last_scan(current).await; }, Err(e) => { eprintln!("Error scanning block {}: {}", current, e); // Attendre un peu avant de réessayer tokio::time::sleep(Duration::from_secs(5)).await; } } } } ``` ### 4. Healthcheck amélioré ```rust async fn start_health_server(port: u16) { let listener = TcpListener::bind(format!("0.0.0.0:{}", port)).await.unwrap(); while let Ok((stream, _)) = listener.accept().await { tokio::spawn(async move { let response = match get_service_state().await { ServiceState::Ready => json!({"status": "ok", "scan_complete": true}), ServiceState::Scanning => json!({"status": "ok", "scan_complete": false, "message": "Scanning in progress"}), ServiceState::Starting => json!({"status": "starting", "scan_complete": false}), ServiceState::Error => json!({"status": "error", "scan_complete": false}), }; let response_str = response.to_string(); let http_response = format!( "HTTP/1.1 200 OK\r\nContent-Length: {}\r\nContent-Type: application/json\r\n\r\n{}", response_str.len(), response_str ); let _ = stream.write_all(http_response.as_bytes()).await; }); } } ``` ## Implémentation recommandée ### Étape 1 : Modifier main.rs 1. Démarrer les serveurs WebSocket et de santé immédiatement 2. Faire le scan en arrière-plan dans une tâche séparée 3. Ajouter un état de service partagé ### Étape 2 : Modifier le healthcheck 1. Retourner l'état du scan dans la réponse 2. Permettre aux services de savoir si le scan est terminé ### Étape 3 : Modifier docker-compose.yml ```yaml sdk_relay: # ... configuration existante ... healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8091/"] interval: 10s timeout: 5s retries: 3 start_period: 30s # Donner plus de temps pour le démarrage initial ``` ### Étape 4 : Modifier les services dépendants ```yaml ihm_client: depends_on: sdk_relay: condition: service_healthy # Ajouter une vérification de l'état du scan environment: - SDK_RELAY_SCAN_TIMEOUT=300 # 5 minutes max d'attente ``` ## Avantages - ✅ Services disponibles immédiatement - ✅ Scan non-bloquant - ✅ Meilleure expérience utilisateur - ✅ Monitoring de l'état du scan - ✅ Récupération d'erreur améliorée ## Migration 1. Implémenter les changements dans sdk_relay 2. Tester avec un scan réduit 3. Déployer en production 4. Surveiller les logs et métriques