57 lines
2.2 KiB
Plaintext
57 lines
2.2 KiB
Plaintext
|
|
@startuml dht_discovery
|
|||
|
|
title Découverte DHT : Provide/FindProviders + SelectByFillRate + dhtCache indexeur
|
|||
|
|
|
|||
|
|
participant "Indexer A\n(nouveau)" as IA
|
|||
|
|
participant "DHT Network" as DHT
|
|||
|
|
participant "Node B\n(bootstrap)" as NodeB
|
|||
|
|
participant "Indexer A\n(existant)" as IAexist
|
|||
|
|
|
|||
|
|
== Inscription indexeur dans la DHT ==
|
|||
|
|
|
|||
|
|
note over IA: Démarrage IndexerService\nstartDHTProvide(fillRateFn)
|
|||
|
|
|
|||
|
|
IA -> IA: Attend adresse routable (max 60s)\nnon-loopback disponible
|
|||
|
|
|
|||
|
|
IA -> DHT: DHT.Bootstrap(ctx)\n→ routing table warmup
|
|||
|
|
|
|||
|
|
loop ticker RecommendedHeartbeatInterval (~20s)
|
|||
|
|
IA -> DHT: DHT.Provide(IndexerCID, true)\n← IndexerCID = CID(sha256("/opencloud/indexers"))
|
|||
|
|
note over DHT: L'indexeur est annoncé comme provider.\nTTL géré par libp2p-kad-dht.\nAuto-expire si Provide() s'arrête.
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
== Cache DHT passif de l'indexeur ==
|
|||
|
|
|
|||
|
|
note over IA: startDHTCacheRefresh()\ngoroutine arrière-plan
|
|||
|
|
|
|||
|
|
IA -> IA: Initial delay 30s (routing table warmup)
|
|||
|
|
|
|||
|
|
loop ticker 2min
|
|||
|
|
IA -> DHT: DiscoverIndexersFromDHT(h, dht, 30)\n← FindProviders(IndexerCID, max=30)
|
|||
|
|
DHT --> IA: []AddrInfo (jusqu'à 30 candidats)
|
|||
|
|
IA -> IA: Filtre self\nSelectByFillRate(filtered, nil, 10)\n→ diversité /24, prior f=0.5 (fill rates inconnus)
|
|||
|
|
IA -> IA: dhtCache = selected (max 10)\n→ utilisé pour Suggestions dans BuildHeartbeatResponse
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
== Découverte côté Node au bootstrap ==
|
|||
|
|
|
|||
|
|
NodeB -> NodeB: ConnectToIndexers → seeds ajoutés\nSendHeartbeat démarré
|
|||
|
|
|
|||
|
|
NodeB -> NodeB: goroutine proactive (après 5s warmup)
|
|||
|
|
|
|||
|
|
alt discoveryDHT == nil (node pur, pas d'IndexerService)
|
|||
|
|
NodeB -> DHT: initNodeDHT(h, seeds)\n← DHT client mode, bootstrappé sur seeds
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
NodeB -> DHT: DiscoverIndexersFromDHT(h, discoveryDHT, need+extra)
|
|||
|
|
DHT --> NodeB: []AddrInfo candidats
|
|||
|
|
|
|||
|
|
NodeB -> NodeB: Filtre self\nSelectByFillRate(candidates, fillRates, need)\n→ pondération w(F) = F×(1-F)\n F=0.2 → w=0.16 (très probable)\n F=0.5 → w=0.25 (max)\n F=0.8 → w=0.16 (peu probable)\n→ filtre diversité /24
|
|||
|
|
|
|||
|
|
loop Pour chaque candidat retenu
|
|||
|
|
NodeB -> NodeB: Indexers.SetAddr(key, &addrInfo)\nNudgeIt() → heartbeat immédiat
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
note over NodeB: Pool enrichi au-delà des seeds.\nScoring commence au premier heartbeat.\nSeeds restent IsSeed=true (stickiness).
|
|||
|
|
|
|||
|
|
@enduml
|