code: func (s *Serf) reconnect() {
  	s.memberLock.RLock()
  
  	// Nothing to do if there are no failed members
  	n := len(s.failedMembers)
  	if n == 0 {
  		s.memberLock.RUnlock()
  		return
  	}
  
  	// Probability we should attempt to reconect is given
  	// by num failed / (num members - num failed - num left)
  	// This means that we probabilistically expect the cluster
  	// to attempt to connect to each failed member once per
  	// reconnect interval
  	numFailed := float32(len(s.failedMembers))
  	numAlive := float32(len(s.members) - len(s.failedMembers) - len(s.leftMembers))
  	if numAlive == 0 {
  		numAlive = 1 // guard against zero divide
  	}
  	prob := numFailed / numAlive
  	if rand.Float32() > prob {
  		s.memberLock.RUnlock()
  		s.logger.Printf("[DEBUG] serf: forgoing reconnect for random throttling")
  		return
  	}
  
  	// Select a random member to try and join
  	idx := rand.Int31n(int32(n))
  	mem := s.failedMembers[idx]
  	s.memberLock.RUnlock()
  
  	// Format the addr
  	addr := net.UDPAddr{IP: mem.Addr, Port: int(mem.Port)}
  	s.logger.Printf("[INFO] serf: attempting reconnect to %v %s", mem.Name, addr.String())
  
  	// Attempt to join at the memberlist level
  	s.memberlist.Join([]string{addr.String()})
  }
docs: // reconnect attempts to reconnect to recently fail nodes.