@startuml failure_indexers_native_falback
title indexers failures → native IsSelfFallback 

participant "Node" as N
participant "Indexer A (crashed)" as IA
participant "Indexer B (crashed)" as IB
participant "Native A" as NA
participant "Native B" as NB

note over N: Active Pool : Indexers = [IA, IB]

== Successive Failures on IA & IB ==
IA ->x N: heartbeat failure (sendHeartbeat err)
IB ->x N: heartbeat failure (sendHeartbeat err)

note over N: doTick() in SendHeartbeat triggers failures\\n→ delete(StaticIndexers[IA]), delete(StaticIndexers[IB])\\n→ delete(StaticIndexerMeta[IA/IB])\\n unique heartbeat goroutine continue.

N -> N: go replenishIndexersFromNative(need=2)

== Replenish attempt — natives switches to self-fallback mode  ==
par Fetch from natives (timeout 6s)
    N -> NA: GET /opencloud/native/indexers/1.0
    NA -> NA: reachableLiveIndexers() → 0 alive indexer\\nFallback : included as himself(IsSelfFallback=true)
    NA --> N: GetIndexersResponse{Indexers:[NA_addr], IsSelfFallback:true}
else
    N -> NB: GET /opencloud/native/indexers/1.0
    NB --> N: GetIndexersResponse{Indexers:[NB_addr], IsSelfFallback:true}
end par

note over N: isFallback=true → resolvePool avoids consensus\\nadmittedAt = time.Time{} (zero)\\nStaticIndexers = {NA_addr} (native as fallback)

N -> NA: SendHeartbeat /opencloud/heartbeat/1.0\\n(native as temporary fallback indexers)

note over NA: responsiblePeers[N] registered.\\nrunOffloadLoop look after real indexers.

== Reprise IA → runOffloadLoop native side ==
IA -> NA: /opencloud/native/subscribe/1.0\\nIndexerRegistration{FillRate: 0}
note over NA: liveIndexers[IA] updated.\\nrunOffloadLoop triggers a real available indexer\\migrate from N to IA.

== Replenish on next heartbeat tick ==
N -> NA: GET /opencloud/native/indexers/1.0
NA --> N: GetIndexersResponse{Indexers:[IA], IsSelfFallback:false}

note over N: isFallback=false → Classic Phase 1 + Phase 2

N -> N: replaceStaticIndexers(pool={IA}, admittedAt)
N -> IA: SendHeartbeat /opencloud/heartbeat/1.0

note over N: Pool restaured. Native self extracted as indexer.

@enduml
