in peer.go [177:215]
func (l *PeerList) choosePeer(prevSelected map[string]struct{}, avoidHost bool) *Peer {
var psPopList []*peerScore
var ps *peerScore
canChoosePeer := func(hostPort string) bool {
if _, ok := prevSelected[hostPort]; ok {
return false
}
if avoidHost {
if _, ok := prevSelected[getHost(hostPort)]; ok {
return false
}
}
return true
}
size := l.peerHeap.Len()
for i := 0; i < size; i++ {
popped := l.peerHeap.popPeer()
if canChoosePeer(popped.HostPort()) {
ps = popped
break
}
psPopList = append(psPopList, popped)
}
for _, p := range psPopList {
heap.Push(l.peerHeap, p)
}
if ps == nil {
return nil
}
l.peerHeap.pushPeer(ps)
ps.chosenCount.Inc()
return ps.Peer
}