func()

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")
}