Aller au contenu principal

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_scripts est mise à jour UNIQUEMENT lorsque le statut de la caméra change (ex: RUNNING -> CRASHED).
  • Horodatage : Lorsqu'un changement se produit, status_updated_at est 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éfaillanceLogique de DétectionAction
Crash ThreadLe 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 > 60sRedémarrage Systématique (Supposition de connexion figée).
Instabilité RéseauStatut 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_scripts pour toute caméra marquée comme running OU crashed.
  • 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 crashed assure 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 (statut stopped) 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.