failbackReconcileWithPeer(); echo date('[Y-m-d H:i:s] ') . "[CLUSTER-FAILBACK] " . ($res['message'] ?? 'OK') . "\n"; exit(0); } // 0. Verrou d'exécution exclusif pour éviter les chevauchements $lockFp = @fopen('/tmp/nexus_cluster_cron.lock', 'c+'); if (!$lockFp || !@flock($lockFp, LOCK_EX | LOCK_NB)) { exit(0); } $db = Database::getConnection(); $cm = new ClusterManager($db); $st = $cm->getSettings(); // 1. Si le cluster n'est pas activé ou que l'auto-sync est désactivée if (empty($st['enabled']) || empty($st['auto_sync'])) { exit(0); } // 2. Règle d'or HA : SEUL le nœud qui détient l'IP Virtuelle active (VIP) émet la réplication // Un nœud passif/standby ne doit JAMAIS écraser le nœud actif ni émettre en boucle croisée $vip = $st['virtual_ip'] ?? ''; if (empty($vip) || !$cm->isVirtualIpActive($vip)) { exit(0); } if (empty($st['peer_ip'])) { exit(0); } // 3. Déclenchement de la réplication vers le pair $result = $cm->pushSyncToPeer(); echo date('[Y-m-d H:i:s] ') . "[CLUSTER-CRON] " . ($result['message'] ?? 'Synchronisation OK') . "\n"; } catch (\Throwable $e) { echo date('[Y-m-d H:i:s] ') . "[CLUSTER-CRON-ERROR] " . $e->getMessage() . "\n"; exit(1); }