5.4 KiB
5.4 KiB
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é)
// Dans main.rs, démarrer les serveurs AVANT le scan
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// ... 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
// 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<Mutex<ServiceState>>) {
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
// 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é
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
- Démarrer les serveurs WebSocket et de santé immédiatement
- Faire le scan en arrière-plan dans une tâche séparée
- Ajouter un état de service partagé
Étape 2 : Modifier le healthcheck
- Retourner l'état du scan dans la réponse
- Permettre aux services de savoir si le scan est terminé
Étape 3 : Modifier docker-compose.yml
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
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
- Implémenter les changements dans sdk_relay
- Tester avec un scan réduit
- Déployer en production
- Surveiller les logs et métriques