Rollback, Kill-Switch et acquittement
TkushPatch intègre une chaîne complète de Rollback et Kill-Switch combinant la révocation serveur (manuelle ou par disjoncteur automatique), le retour arrière du moteur natif Rust sur le téléphone, le hook de nettoyage local du SDK tk_ota_push et l'acquittement d'incident (acknowledgeRollback) par les équipes Support N3 / SRE.
Vue d'ensemble du cycle de vie d'un Rollback
- Détection de l'anomalie : Constat d'un dysfonctionnement critique sur un correctif publié.
- Neutralisation (Kill-Switch) : L'administrateur exécute
tk-ota-push rollbackou clique sur Rollback dans la console. - Désactivation serveur : Le statut passe à
ROLLED_BACKet le taux de diffusion est ramené à0%. - Réaction des applications : Dès leur prochaine vérification, les terminaux révoquent le patch et repassent sur la version saine.
1. Déclencher le Kill-Switch d'un patch (ROLLED_BACK)
La révocation d'un patch s'effectue en 1 clic depuis la Console Web ou en ligne de commande via l'API d'administration (OtaAdminController.rollbackPatch) :
curl -X POST "$OTA_SERVER_URL/api/admin/v1/patches/$PATCH_ID/rollback" \
-H "Authorization: Bearer $OTA_API_KEY"
Effets immédiats côté serveur (Serveur TkushPatch)
- Le statut du patch passe à
ROLLED_BACKet sonrolloutPercentageest forcé à0. - Le cache L1/L2 de la Release est immédiatement invalidé (
evictAllForRelease). - Lors des appels suivants à
/api/v1/patches/check, le numéro du patch figure dans la listerolled_back_patch_numbersrenvoyée au moteur natif Rust, qui désinstalle immédiatement le patch révoqué. - Une entrée d'audit immuable
PATCH_ROLLBACK_TRIGGEREDest enregistrée sur le serveur.
Disjoncteur automatique (Circuit Breaker)
Dans Serveur TkushPatch, le disjoncteur automatique est activé par défaut avec :
circuitBreakerMinSampleSize = 10(au moins 10 événements télémétriques reçus pour ce patch)circuitBreakerFailureRateThreshold = 0.05(5 %de taux d'échec)
Si ce seuil est franchi, le serveur révoque automatiquement le patch sans attendre une intervention humaine.
2. Résilience côté application mobile (onRollbackDetected)
Lorsqu'un appareil subit un rollback (par exemple du Patch #2 vers le Patch #1 ou vers le binaire Store d'origine null), un changement de schéma local (SQLite, Hive, SharedPreferences) introduit par le Patch #2 pourrait provoquer une erreur dans l'ancienne version restaurée.
La méthode verifyStartupAndHandleRollback() de TkOtaPush (appelée automatiquement au début de syncWithRemoteConfig) compare le patch en cours d'exécution avec le dernier patch enregistré par OtaRollbackTracker (current_patch < last_executed_patch) :
final ota = TkOtaPush.init(
appReleaseVersion: '1.0.0+3',
onRollbackDetected: (OtaRollbackEvent event) async {
debugPrint(
'Rollback détecté : #${event.previousPatchNumber} -> #${event.restoredPatchNumber}',
);
// Purger le cache local pour garantir la stabilité post-rollback
},
);
3. Acquittement d'un Rollback par appareil (acknowledgeRollback)
Dans l'inventaire de flotte (GET /api/admin/v1/devices et Console Web /support), tout téléphone ayant remonté au moins un événement d'échec ou de rollback (failureCount > 0) apparaît avec l'indicateur rollbackTriggered: true (Rollback Actif).
Une fois l'incident résolu (par exemple après publication d'un nouveau patch correctif), l'opérateur peut acquitter l'alerte sans jamais altérer ni supprimer l'historique télémétrique immuable.
Règle d'évaluation exacte (OtaAdminController.listDiscoveredDevices)
Le serveur stocke l'horodatage rollbackAcknowledgedAt dans ota_device_registry et évalue :
ackedAfterLastFailure = (rollbackAcknowledgedAt != null)
&& (latestFailureAt != null)
&& !rollbackAcknowledgedAt.isBefore(latestFailureAt)
rollbackTriggered = (failureCount > 0) && !ackedAfterLastFailure
- Tant qu'aucun nouvel échec ne survient après
rollbackAcknowledgedAt, l'appareil est comptabilisé comme Sain (rollbackTriggered: false, tandis querawFailureDetectedreste àtruepour la traçabilité). - Si un nouvel échec survient sur un patch ultérieur (
latestFailureAt > rollbackAcknowledgedAt), l'alerterollbackTriggered: truese réactive automatiquement.
Commandes d'acquittement et de réinitialisation
Vous pouvez cibler l'appareil par son UUID complet (client_id) ou le rechercher par son Code Court Support N3 (#6959347F, obtenu via ota.readShortSupportCode()) :
# 1. Acquitter l'alerte Rollback d'un appareil
curl -X POST "$OTA_SERVER_URL/api/admin/v1/devices/$CLIENT_ID" \
-H "Authorization: Bearer $OTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"acknowledgeRollback": true}'
# 2. Réinitialiser l'acquittement (remettre rollbackAcknowledgedAt à null)
curl -X POST "$OTA_SERVER_URL/api/admin/v1/devices/$CLIENT_ID" \
-H "Authorization: Bearer $OTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"resetRollbackAck": true}'