Résilience & Gestion des Crashes
Le système FirstBreath Vision est conçu pour être résilient aux pannes réseau, aux plantages de caméras et aux redémarrages de conteneurs. Cette page détaille les mécanismes robustes de gestion des crashes et d'auto-récupération implémentés dans le service camera-manager.
Architecture
La logique de résilience est centralisée dans le Camera Manager, qui orchestre le cycle de vie des connexions caméras (threads), que ce soit en mode Batch ou Distribué.
Mécanismes Clés
1. Boucle de Surveillance de Santé (Health Monitor)
Un thread dédié en arrière-plan dans manager.py interroge le statut de tous les threads de caméras actifs toutes les 10 secondes. Il utilise une Machine à État interne pour décider quand intervenir et éviter les redémarrages intempestifs (flapping) pour des problèmes mineurs.
- Mises à jour Événementielles : Pour minimiser les E/S en base de données, la table
running_scriptsest mise à jour UNIQUEMENT lorsque le statut de la caméra change (ex:RUNNING->CRASHED). - Horodatage : Lorsqu'un changement se produit,
status_updated_atest défini àNOW(). Cet horodatage précis permet à l'interface utilisateur de calculer "Depuis quand" la caméra est dans cet état. - Pas de Heartbeat Périodique : Nous évitons délibérément d'écrire en base si le statut est stable ("Pas de nouvelles, bonnes nouvelles"), réduisant considérablement la charge de la base de données.
2. Stratégie d'Auto-Redémarrage
Le système récupère automatiquement de divers modes de défaillance :
| Mode de Défaillance | Logique de Détection | Action |
|---|---|---|
| Crash Thread | Le thread CameraReader attrape une exception et met status='CRASHED' | Suppression + Ajout (Remove + Add) immédiat de la caméra. |
| Flux Bloqué (Stalled) | Statut est RUNNING mais last_frame_time > 60s | Redémarrage Systématique (Supposition de connexion figée). |
| Instabilité Réseau | Statut est RECONNECTING | < 30s : Aucune Action (Debounce) > 30s : Marqué CRASHED en DB> 60s : Redémarrage Forcé |
3. Récupération au Démarrage (Persistance)
Le service camera-manager est sans état (stateless) en mémoire mais avec état (stateful) via la base de données.
- Au Démarrage : Le service exécute
load_snapshot(). - Logique : Il interroge la table
running_scriptspour toute caméra marquée commerunningOUcrashed. - Effet : Si le conteneur a été redémarré (mise à jour, crash, redémarrage manuel), toutes les caméras précédemment actives sont automatiquement réinitialisées.
4. Arrêt Propre (Graceful Shutdown)
Pour supporter efficacement la Récupération au Démarrage, nous devons savoir quelles caméras devraient tourner.
- Sur SIGTERM (Docker Stop) : Un gestionnaire de signal intercepte la demande d'arrêt.
- Action : Il exécute
UPDATE running_scripts SET status='crashed' WHERE status='running'. - Pourquoi ? : Les marquer comme
crashedassure qu'elles seront reprises par la logique de Récupération au Démarrage au prochain boot. Les caméras explicitement arrêtées par l'utilisateur (statutstopped) restent arrêtées.
Contrôle Manuel
- Démarrer : API envoie Redis
start-> Manager ajoute caméra -> DB set àrunning. - Arrêter : API envoie Redis
stop-> Manager supprime caméra -> DB set àstopped. - Résultat : Une caméra arrêtée manuellement ne redémarrera pas automatiquement au redémarrage du conteneur, ce qui est le comportement attendu.