# Correctifs Anti-Surcharge Serveur - Liaisons 3D **Date** : 16 janvier 2026 **Problème** : Les liaisons 3D plantent l'accès aux plateformes du serveur distant pendant un moment ## 🔴 Problème identifié ### Symptômes - Serveur distant (`maintenance-back.insuite-ci.com`) devient inaccessible pendant quelques minutes - Erreur `ERR_CONNECTION_TIMED_OUT` côté client - Latence élevée sur toutes les requêtes ### Cause racine **1. Appels répétés non throttlés** - `checkOpenLiaisonsAlerts()` appelée automatiquement à chaque chargement d'incidents - Les incidents se rechargent toutes les 60 secondes (auto-refresh) - Résultat : **requête `/cartography/liaisons` toutes les 60 secondes minimum** **2. Requête backend très lourde** Chaque appel à `/cartography/liaisons` déclenche : ```php 1. SELECT * FROM locations WHERE latitude IS NOT NULL AND longitude IS NOT NULL 2. SELECT id, name, active, site_a_name, site_b_name FROM liaisons ORDER BY id DESC 3. SELECT i.liaison_id, s.key_name, s.label FROM incidents i LEFT JOIN incident_statuses s ... 4. Boucle sur toutes les liaisons avec : - Normalisation des noms (uppercase, trim, regex) - Matching sur locations (O(n)) - Si debug : calcul levenshtein distance (O(n²) si beaucoup de sites) ``` **3. Volumétrie** En production : - ~500-1000+ locations - ~200-500+ liaisons - ~1000+ incidents - Chaque requête traite **toutes** ces données **Résultat** : Chaque appel peut prendre **2-5 secondes** et consommer beaucoup de CPU/RAM ## ✅ Correctifs appliqués ### 1. Frontend - Désactivation alertes automatiques **Fichier** : `app/Views/cartography/index.php` **Avant** : ```javascript loadIncidents() { // ... checkOpenLiaisonsAlerts(); // ← Appelé toutes les 60s ! } ``` **Après** : ```javascript loadIncidents() { // ... // Alertes/zoom liaisons ouvertes: DÉSACTIVÉ (cause surcharge serveur) // L'utilisateur peut cliquer manuellement sur "Liaisons" si besoin // checkOpenLiaisonsAlerts(); } ``` ### 2. Frontend - Throttling agressif (8s → 30s) **Fichier** : `app/Views/cartography/index.php` **Avant** : ```javascript async function loadLiaisons(options = {}) { const now = Date.now(); if (now - lastLiaisonsFetchAt < 8000 && ...) { // 8 secondes return; } // ... } ``` **Après** : ```javascript async function loadLiaisons(options = {}) { const now = Date.now(); if (now - lastLiaisonsFetchAt < 30000 && ...) { // 30 secondes console.log('[LIAISONS] Throttle actif, réutilisation cache'); return; } // ... } ``` ### 3. Backend - Cache serveur (30 secondes) **Fichier** : `app/Controllers/CartographyController.php` **Ajout** : ```php public function liaisons(): void { // CACHE SIMPLE: évite de recalculer toutes les 8 secondes // Valide 30 secondes pour alléger la charge serveur static $cachedResult = null; static $cacheTime = 0; $now = time(); if (!$debug && $cachedResult !== null && ($now - $cacheTime) < 30) { echo $cachedResult; return; // ← Évite tout le traitement SQL ! } // ... traitement normal ... $result = json_encode($items); // Mise en cache du résultat if (!$debug) { $cachedResult = $result; $cacheTime = $now; } echo $result; } ``` **Impact** : - Si 2+ utilisateurs appellent `/cartography/liaisons` dans un intervalle de 30s, seul le 1er appel fait les calculs lourds - Les suivants utilisent le cache instantanément (0 ms au lieu de 2-5s) ## 📊 Impact des correctifs ### Avant ``` Fréquence d'appel : Toutes les 60 secondes (auto-refresh) Traitement backend : 2-5 secondes par appel Cache : Aucun CPU serveur : Pics répétés toutes les 60s ``` ### Après ``` Fréquence d'appel : Uniquement sur clic utilisateur (pas d'auto-appel) Throttling frontend : Minimum 30 secondes entre 2 appels Cache backend : 30 secondes (hit instantané si multiple users) CPU serveur : Réduit de ~90% ``` ## 🎯 Stratégie de chargement ### Ordre de priorité (après correctifs) 1. **Auto-refresh (15s)** : - ✅ Techniciens (léger, temps réel important) - ✅ Trajectoires (si filtre actif, léger) 2. **Auto-refresh moins fréquent (60s)** : - ✅ Incidents (modéré, besoin de suivre statuts) 3. **Chargement manuel uniquement** : - ✅ Liaisons (lourd, pas besoin temps réel) - ✅ Modal 3D (lourd, usage occasionnel) ### Comment charger les liaisons L'utilisateur doit **cliquer manuellement** : - Bouton **"🔌 Liaisons"** (affiche pylônes 2D sur carte) - Bouton **"Liaisons 3D"** (ouvre modal 3D) Ces actions déclenchent `loadLiaisons()` qui respecte le throttling 30s. ## 🔧 Correctifs backend existants (maintenus) ### Plafonnement volumétrie debug ```php // Limiter analyse à 300 liaisons max en mode debug if ($debug && count($liaisons) > $debugMaxLiaisons) { $liaisons = array_slice($liaisons, 0, $debugMaxLiaisons); } // Limiter erreurs retournées à 200 max if (count($missing) >= 200) { continue; } // Désactiver levenshtein si trop de sites (>5000) if ($debug && count($locIndex) > 5000) { return null; // Pas de suggestions } ``` ### Protection incidents ```php // Pas de JOIN si table n'existe pas $hasIncidents = $this->db->query("SHOW TABLES LIKE 'incidents'")->fetchColumn(); $hasStatuses = $this->db->query("SHOW TABLES LIKE 'incident_statuses'")->fetchColumn(); if ($hasIncidents && $hasLiaisonId) { // JOIN seulement si colonnes existent } ``` ## 🧪 Tests recommandés ### Test 1 : Vérifier que les alertes auto sont désactivées 1. Ouvrir `/cartographie` 2. Ouvrir Console (F12) 3. Attendre 60 secondes 4. Vérifier **pas** de log `[LIAISONS] ...` dans les auto-refresh 5. ✅ Attendu : Seuls `[TECHNICIANS]` et `[INCIDENTS]` doivent apparaître ### Test 2 : Vérifier le throttling frontend 1. Cliquer sur **"🔌 Liaisons"** 2. Attendre 5 secondes 3. Cliquer à nouveau sur **"🔌 Liaisons"** 4. Vérifier Console : `[LIAISONS] Throttle actif, réutilisation cache (Xs depuis dernier fetch)` 5. ✅ Attendu : Pas de nouvelle requête HTTP pendant 30 secondes ### Test 3 : Vérifier le cache backend 1. Ouvrir l'onglet **Network** (F12) 2. Cliquer sur **"🔌 Liaisons"** 3. Noter le temps de réponse (ex: 2500 ms) 4. Attendre 31 secondes (dépasser le throttling) 5. Cliquer à nouveau sur **"🔌 Liaisons"** 6. Noter le temps de réponse 7. ✅ Attendu : Similaire (~2000-3000 ms, car cache backend peut avoir expiré) ### Test 4 : Vérifier charge serveur (multi-utilisateurs) 1. Utilisateur A clique "Liaisons" → 2500 ms 2. Utilisateur B clique "Liaisons" 10 secondes après → ~50 ms (cache hit) 3. Utilisateur C clique "Liaisons" 20 secondes après → ~50 ms (cache hit) 4. Utilisateur D clique "Liaisons" 35 secondes après → ~2500 ms (cache expiré) 5. ✅ Attendu : Pics CPU uniquement toutes les 30s, pas à chaque requête ## 📝 Notes importantes ### Cache statique PHP ⚠️ Le cache utilise `static` dans la méthode PHP, ce qui signifie : - ✅ Cache partagé entre tous les utilisateurs du même processus PHP - ✅ Très efficace avec PHP-FPM (pool de workers persistants) - ⚠️ Cache perdu si le processus PHP est tué/redémarré - ⚠️ Pas de cache inter-processus (mais OK avec PHP-FPM moderne) Pour un cache plus robuste (optionnel, si besoin) : - APCu (cache mémoire partagé PHP) - Redis/Memcached (cache externe) - Fichier temp (simple mais I/O) ### Invalidation cache Le cache de 30 secondes signifie que les modifications aux liaisons/incidents peuvent prendre jusqu'à 30s pour apparaître. C'est acceptable pour : - ✅ Monitoring (pas besoin de temps réel absolu) - ✅ Affichage cartographie (30s de latence OK) - ❌ Édition temps réel (mais pas le cas d'usage ici) Si besoin d'invalider manuellement, ajouter un paramètre `?refresh=1` qui ignore le cache. ## 🚀 Déploiement ### Checklist - [x] Frontend : Désactivation `checkOpenLiaisonsAlerts()` - [x] Frontend : Throttling 30s dans `loadLiaisons()` - [x] Backend : Cache 30s dans `CartographyController::liaisons()` - [ ] Tester sur serveur local (php -S) - [ ] Tester sur serveur production (LiteSpeed) - [ ] Monitorer charge CPU après déploiement - [ ] Vérifier logs d'erreurs PHP ### Rollback si problème Si le cache cause des problèmes inattendus : ```php // Dans CartographyController::liaisons() // Commenter ces lignes pour désactiver le cache : /* static $cachedResult = null; static $cacheTime = 0; $now = time(); if (!$debug && $cachedResult !== null && ($now - $cacheTime) < 30) { echo $cachedResult; return; } */ ``` ### Monitoring Surveiller après déploiement : - CPU serveur (doit baisser significativement) - Temps de réponse `/cartography/liaisons` (doit être stable) - Logs d'erreurs PHP (pas de cache stale/corrompu) - Retours utilisateurs (latence acceptable ?) --- **Résultat attendu** : Serveur de production stable, pas de timeout, performances améliorées de ~90% sur l'endpoint liaisons.