code: func (c *Client) next() (*conn, error) {
  	// We do round-robin here.
  	// TODO(oe) This should be a pluggable strategy, like the Selector in the official clients.
  	c.connsMu.Lock()
  	defer c.connsMu.Unlock()
  
  	i := 0
  	numConns := len(c.conns)
  	for {
  		i++
  		if i > numConns {
  			break // we visited all conns: they all seem to be dead
  		}
  		c.cindex++
  		if c.cindex >= numConns {
  			c.cindex = 0
  		}
  		conn := c.conns[c.cindex]
  		if !conn.IsDead() {
  			return conn, nil
  		}
  	}
  
  	// We have a deadlock here: All nodes are marked as dead.
  	// If sniffing is disabled, connections will never be marked alive again.
  	// So we are marking them as alive--if sniffing is disabled.
  	// They'll then be picked up in the next call to PerformRequest.
  	if !c.snifferEnabled {
  		c.errorf("elastic: all %d nodes marked as dead; resurrecting them to prevent deadlock", len(c.conns))
  		for _, conn := range c.conns {
  			conn.MarkAsAlive()
  		}
  	}
  
  	// We tried hard, but there is no node available
  	return nil, errors.Wrap(ErrNoClient, "no available connection")
  }
docs: // next returns the next available connection, or ErrNoClient.