code: func Join(joinAddr []string, id, addr string, meta map[string]string, skip bool) (string, error) {
  	var err error
  	var j string
  	logger := log.New(os.Stderr, "[cluster-join] ", log.LstdFlags)
  
  	for i := 0; i < numAttempts; i++ {
  		for _, a := range joinAddr {
  			j, err = join(a, id, addr, meta, skip)
  			if err == nil {
  				// Success!
  				return j, nil
  			}
  		}
  		logger.Printf("failed to join cluster at %s, sleeping %s before retry", joinAddr, attemptInterval)
  		time.Sleep(attemptInterval)
  	}
  	logger.Printf("failed to join cluster at %s, after %d attempts", joinAddr, numAttempts)
  	return "", err
  }
docs: // Join attempts to join the cluster at one of the addresses given in joinAddr.
  // It walks through joinAddr in order, and sets the node ID and Raft address of
  // the joining node as id addr respectively. It returns the endpoint
  // successfully used to join the cluster.