@startuml 22_failure_both_natives title F4 — Panne des 2 natifs → fallback pool pré-validé participant "Node" as N participant "Indexer A\\n(vivant)" as IA participant "Indexer B\\n(vivant)" as IB participant "Native A\\n(crashé)" as NA participant "Native B\\n(crashé)" as NB note over N: Pool actif : StaticIndexers = [IA, IB]\\nStaticNatives = [NA, NB]\\nAdmittedAt[IA] et AdmittedAt[IB] posés (stables) == Panne simultanée NA et NB == NA ->x N: stream reset NB ->x N: stream reset N -> N: AfterDelete(NA) + AfterDelete(NB)\\nStaticNatives = {} (vide) == replenishNativesFromPeers (sans résultat) == N -> N: fetchNativeFromNatives() → aucun natif vivant N -> IA: GET /opencloud/indexer/natives/1.0 IA --> N: GetNativesResponse{Natives:[NA,NB]} note over N: NA et NB connus mais non joignables.\\nAucun nouveau natif trouvé. == Fallback : pool d'indexeurs conservé == note over N: isFallback = true\\nStaticIndexers conservé tel quel [IA, IB]\\n(dernier pool validé avec AdmittedAt != zero)\\nRisque D19 atténué : quorum natif = 0 → fallback accepté note over N: Heartbeats IA et IB continuent normalement.\\nPool d'indexeurs opérationnel sans natifs. N -> IA: SendHeartbeat /opencloud/heartbeat/1.0 (continue) N -> IB: SendHeartbeat /opencloud/heartbeat/1.0 (continue) == retryLostNative (30s ticker) == loop toutes les 30s N -> N: retryLostNative()\\ntente reconnexion NA et NB N -> NA: dial (échec) N -> NB: dial (échec) note over N: Retry sans résultat.\\nPool indexeurs maintenu en fallback. end == Reprise natifs == NA -> NA: redémarrage NB -> NB: redémarrage N -> NA: dial (succès) N -> NA: SendHeartbeat /opencloud/heartbeat/1.0 N -> NB: SendHeartbeat /opencloud/heartbeat/1.0 note over N: StaticNatives = [NA, NB] restauré\\nisFallback = false == Re-consensus pool indexeurs (optionnel) == par Consensus Phase 1 N -> NA: /opencloud/native/consensus/1.0\\nConsensusRequest{Candidates:[IA,IB]} NA --> N: ConsensusResponse{Trusted:[IA,IB]} else N -> NB: /opencloud/native/consensus/1.0 NB --> N: ConsensusResponse{Trusted:[IA,IB]} end par note over N: Pool [IA,IB] reconfirmé.\\nisFallback = false. AdmittedAt[IA,IB] rafraîchi. @enduml