From 4bd0f8b0955844cbe1771b26a7c154669c9aaa4f Mon Sep 17 00:00:00 2001 From: sorcier Date: Sat, 7 Nov 2026 01:49:10 +0100 Subject: [PATCH] fix(cluster): purge subscription_persistence in AstDB replication to prevent dead BLF dialogues --- scripts/cluster/notify_master.sh | 1 + scripts/nexus-cluster | 9 +++++++-- src/ClusterManager.php | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/cluster/notify_master.sh b/scripts/cluster/notify_master.sh index 307845c..451fce9 100755 --- a/scripts/cluster/notify_master.sh +++ b/scripts/cluster/notify_master.sh @@ -49,6 +49,7 @@ fi # Leur raccrochage réinitialise immédiatement les hints à l'état Idle et éteint les BLF. if pidof asterisk >/dev/null 2>&1; then /usr/sbin/asterisk -rx "channel request hangup all" >> "$LOG_FILE" 2>&1 || true + /usr/sbin/asterisk -rx "database deltree subscription_persistence" >> "$LOG_FILE" 2>&1 || true /usr/sbin/asterisk -rx "pjsip reload" >> "$LOG_FILE" 2>&1 || true /usr/sbin/asterisk -rx "pjsip send register *" >> "$LOG_FILE" 2>&1 || true for reg in $(/usr/sbin/asterisk -rx "pjsip show registrations" 2>/dev/null | grep -o '[a-zA-Z0-9_\-]*-reg' | sort -u); do diff --git a/scripts/nexus-cluster b/scripts/nexus-cluster index b5a054e..d2b7154 100755 --- a/scripts/nexus-cluster +++ b/scripts/nexus-cluster @@ -86,15 +86,20 @@ case "$CMD" in # 2. Si Asterisk tourne, injection via son moteur interne database query # Cela garantit l'absence totale de verrou SQLite (database is locked) et préserve les descripteurs ouverts + # IMPORTANT : Ne jamais répliquer /subscription_persistence/ car les dialogues SIP BLF sont des objets en RAM + # propres à l'instance Asterisk d'origine. Les purger force le nouveau Master à envoyer 481, ce qui incite + # immédiatement les téléphones (Yealink T46S, T54W) à réémettre un dialogue BLF propre en 25ms. if pidof asterisk >/dev/null 2>&1; then /usr/sbin/asterisk -rx "database query \"ATTACH '$SRC' AS src;\"" >/dev/null 2>&1 || true /usr/sbin/asterisk -rx "database query \"DELETE FROM astdb WHERE key LIKE '/registrar/%';\"" >/dev/null 2>&1 || true /usr/sbin/asterisk -rx "database query \"INSERT INTO astdb SELECT * FROM src.astdb WHERE key LIKE '/registrar/%';\"" >/dev/null 2>&1 || true - /usr/sbin/asterisk -rx "database query \"INSERT OR REPLACE INTO astdb SELECT * FROM src.astdb WHERE key NOT LIKE '/registrar/%';\"" >/dev/null 2>&1 || true + /usr/sbin/asterisk -rx "database query \"INSERT OR REPLACE INTO astdb SELECT * FROM src.astdb WHERE key NOT LIKE '/registrar/%' AND key NOT LIKE '/subscription_persistence/%';\"" >/dev/null 2>&1 || true /usr/sbin/asterisk -rx "database query \"DETACH src;\"" >/dev/null 2>&1 || true + /usr/sbin/asterisk -rx "database deltree subscription_persistence" >/dev/null 2>&1 || true else - # Asterisk arrêté : copie directe intègre + # Asterisk arrêté : copie directe intègre en purgeant les souscriptions zombies cp -f "$SRC" "$DEST" + sqlite3 "$DEST" "DELETE FROM astdb WHERE key LIKE '/subscription_persistence/%';" 2>/dev/null || true chown asterisk:asterisk "$DEST" 2>/dev/null || true chmod 664 "$DEST" 2>/dev/null || true fi diff --git a/src/ClusterManager.php b/src/ClusterManager.php index 119133e..a59e879 100644 --- a/src/ClusterManager.php +++ b/src/ClusterManager.php @@ -527,6 +527,8 @@ class ClusterManager if (file_exists($tmpAstdb) && filesize($tmpAstdb) > 0) { $integrity = trim(shell_exec("sqlite3 " . escapeshellarg($tmpAstdb) . " 'PRAGMA integrity_check;' 2>/dev/null") ?? ''); if ($integrity === 'ok') { + // Purger les souscriptions persistantes PJSIP de l'archive (incompatibles entre instances Asterisk) + shell_exec("sqlite3 " . escapeshellarg($tmpAstdb) . " \"DELETE FROM astdb WHERE key LIKE '/subscription_persistence/%';\" 2>/dev/null || true"); $hasAstdb = true; } else { @unlink($tmpAstdb);