in swim/self_evict.go [181:229]
func (s *selfEvict) evict() {
s.lock.Lock()
phase := s.transitionTo(evicting)
s.lock.Unlock()
s.node.memberlist.SetLocalStatus(Faulty)
numberOfPingableMembers := s.node.memberlist.NumPingableMembers()
maxNumberOfPings := int(math.Ceil(float64(numberOfPingableMembers) * s.options.PingRatio))
// final number of members to ping should not exceed any of:
numberOfPings := util.Min(
s.node.disseminator.maxP, // the piggyback counter
numberOfPingableMembers, // the number of members we can ping
maxNumberOfPings, // a configured percentage of members
)
if numberOfPings <= 0 {
// there are no nodes to be pinged, a value below 0 can be caused by a
// negative ping ratio
return
}
// select the members we are going to ping
targets := s.node.memberlist.RandomPingableMembers(numberOfPings, nil)
phase.numberOfPings = len(targets)
s.logger.WithFields(bark.Fields{
"numberOfPings": phase.numberOfPings,
"targets": targets,
}).Debug("starting proactive gossip on self evict")
var wg sync.WaitGroup
wg.Add(len(targets))
for _, target := range targets {
go func(target Member) {
defer wg.Done()
_, err := sendPing(s.node, target.address(), s.node.pingTimeout)
if err == nil {
atomic.AddInt32(&phase.numberOfSuccessfulPings, 1)
}
}(target)
}
wg.Wait()
s.logger.WithFields(bark.Fields{
"numberOfPings": phase.numberOfPings,
"numberOfSuccessfulPings": phase.numberOfSuccessfulPings,
}).Debug("finished proactive gossip on self evict")
}