mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-09 00:43:13 +00:00
feat: implement weighted random peer selection for load balancing
Use probabilistic distribution based on peer quality scores, giving all peers opportunity while favoring better-performing ones. Selection probability is inversely proportional to score. Part of https://github.com/codex-storage/nim-codex/issues/974
This commit is contained in:
parent
8e8d9f8e60
commit
0fbca17269
@ -842,8 +842,39 @@ proc blockexcTaskRunner(self: BlockExcEngine) {.async: (raises: []).} =
|
||||
|
||||
info "Exiting blockexc task runner"
|
||||
|
||||
proc selectRandom*(peers: seq[BlockExcPeerCtx]): BlockExcPeerCtx =
|
||||
Rng.instance.sample(peers)
|
||||
proc selectRandom*(
|
||||
peers: seq[BlockExcPeerCtx]
|
||||
): BlockExcPeerCtx {.gcsafe, raises: [].} =
|
||||
if peers.len == 1:
|
||||
return peers[0]
|
||||
|
||||
proc evalPeerScore(peer: BlockExcPeerCtx): float =
|
||||
let
|
||||
loadPenalty = peer.blocksRequested.len.float * 2.0
|
||||
successRate =
|
||||
if peer.exchanged > 0:
|
||||
peer.exchanged.float / (peer.exchanged + peer.blocksRequested.len).float
|
||||
else:
|
||||
0.5
|
||||
failurePenalty = (1.0 - successRate) * 5.0
|
||||
return loadPenalty + failurePenalty
|
||||
|
||||
let
|
||||
scores = peers.mapIt(evalPeerScore(it))
|
||||
maxScore = scores.max() + 1.0
|
||||
weights = scores.mapIt(maxScore - it)
|
||||
|
||||
var totalWeight = 0.0
|
||||
for w in weights:
|
||||
totalWeight += w
|
||||
|
||||
var r = rand(totalWeight)
|
||||
for i, weight in weights:
|
||||
r -= weight
|
||||
if r <= 0.0:
|
||||
return peers[i]
|
||||
|
||||
return peers[^1]
|
||||
|
||||
proc new*(
|
||||
T: type BlockExcEngine,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user