// Fill the connection pool
187850
func (pool *hostConnPool) fill() {
	pool.mu.RLock()
	// avoid filling a closed pool, or concurrent filling
	if pool.closed || pool.filling {
		pool.mu.RUnlock()
		return
	}

	// determine the filling work to be done
	startCount := len(pool.conns)
	fillCount := pool.size - startCount

	// avoid filling a full (or overfull) pool
	if fillCount <= 0 {
		pool.mu.RUnlock()
		return
	}

	// switch from read to write lock
	pool.mu.RUnlock()
	pool.mu.Lock()

	// double check everything since the lock was released
	startCount = len(pool.conns)
	fillCount = pool.size - startCount
	if pool.closed || pool.filling || fillCount <= 0 {
		// looks like another goroutine already beat this
		// goroutine to the filling
		pool.mu.Unlock()
		return
	}

	// ok fill the pool
	pool.filling = true

	// allow others to access the pool while filling
	pool.mu.Unlock()
	// only this goroutine should make calls to fill/empty the pool at this
	// point until after this routine or its subordinates calls
	// fillingStopped

	// fill only the first connection synchronously
	if startCount == 0 {
		err := pool.connect()
		pool.logConnectErr(err)

		if err != nil {
			// probably unreachable host
			pool.fillingStopped(true)

			// this is call with the connection pool mutex held, this call will
			// then recursively try to lock it again. FIXME
			if pool.session.cfg.ConvictionPolicy.AddFailure(err, pool.host) {
				go pool.session.handleNodeDown(pool.host.ConnectAddress(), pool.port)
			}
			return
		}

		// filled one
		fillCount--
	}

	// fill the rest of the pool asynchronously
	go func() {
		err := pool.connectMany(fillCount)

		// mark the end of filling
		pool.fillingStopped(err != nil)
	}()
}
633640
func FillRels(resource interface{}, rels Relations) {
	if hypermediaRel, ok := resource.(HyperfieldResource); ok {
		HyperFieldRelations(hypermediaRel, rels)
	}

	if hypermediaRel, ok := resource.(HypermediaResource); ok {
		hypermediaRel.HypermediaRels(rels)
	}
}
386821
func (b *BigIP) AddPool(config *Pool) error {
	return b.post(config, uriLtm, uriPool)
}
972834
func (cp *ConnectionPool) WaitCount() int64 {
	p := cp.pool()
	if p == nil {
		return 0
	}
	return p.WaitCount()
}
377834
func NewConnectionPool(name string, capacity int, idleTimeout time.Duration, dnsResolutionFrequency time.Duration) *ConnectionPool {
	cp := &ConnectionPool{capacity: capacity, idleTimeout: idleTimeout, resolutionFrequency: dnsResolutionFrequency}
	if name == "" || usedNames[name] {
		return cp
	}
	usedNames[name] = true
	stats.NewGaugeFunc(name+"Capacity", "Connection pool capacity", cp.Capacity)
	stats.NewGaugeFunc(name+"Available", "Connection pool available", cp.Available)
	stats.NewGaugeFunc(name+"Active", "Connection pool active", cp.Active)
	stats.NewGaugeFunc(name+"InUse", "Connection pool in-use", cp.InUse)
	stats.NewGaugeFunc(name+"MaxCap", "Connection pool max cap", cp.MaxCap)
	stats.NewCounterFunc(name+"WaitCount", "Connection pool wait count", cp.WaitCount)
	stats.NewCounterDurationFunc(name+"WaitTime", "Connection pool wait time", cp.WaitTime)
	stats.NewGaugeDurationFunc(name+"IdleTimeout", "Connection pool idle timeout", cp.IdleTimeout)
	stats.NewGaugeFunc(name+"IdleClosed", "Connection pool idle closed", cp.IdleClosed)
	return cp
}
666159
func NewKamEvapiPool(maxconns int, kamAddr, connId string, reconnects int, l *log.Logger) (*KamEvapiPool, error) {
	pool := &KamEvapiPool{kamAddr: kamAddr, connId: connId, reconnects: reconnects, logger: l}
	pool.allowedConns = make(chan struct{}, maxconns)
	var emptyConn struct{}
	for i := 0; i < maxconns; i++ {
		pool.allowedConns <- emptyConn // Empty initiate so we do not need to wait later when we pop
	}
	pool.conns = make(chan *KamEvapi, maxconns)
	return pool, nil
}
357249
func (pool *hostConnPool) connectMany(count int) error {
	if count == 0 {
		return nil
	}
	var (
		wg         sync.WaitGroup
		mu         sync.Mutex
		connectErr error
	)
	wg.Add(count)
	for i := 0; i < count; i++ {
		go func() {
			defer wg.Done()
			err := pool.connect()
			pool.logConnectErr(err)
			if err != nil {
				mu.Lock()
				connectErr = err
				mu.Unlock()
			}
		}()
	}
	// wait for all connections are done
	wg.Wait()

	return connectErr
}
93743
func fill(src, dest interface{}) (err error) {
	defer func() {
		if r := recover(); r != nil {
			d := reflect.TypeOf(dest)
			s := reflect.TypeOf(src)
			err = fmt.Errorf("the fill destination should be a pointer to a `%s`, but you used a `%s`", s, d)
		}
	}()

	reflect.ValueOf(dest).Elem().Set(reflect.ValueOf(src))

	return err
}
1247197
func (pp *TxPreparedPool) FetchAll() []*TxConnection {
	pp.mu.Lock()
	defer pp.mu.Unlock()
	conns := make([]*TxConnection, 0, len(pp.conns))
	for _, c := range pp.conns {
		conns = append(conns, c)
	}
	pp.conns = make(map[string]*TxConnection, pp.capacity)
	pp.reserved = make(map[string]error)
	return conns
}
435885
func (nc *Conn) connect() error {
	var returnedErr error

	// Create actual socket connection
	// For first connect we walk all servers in the pool and try
	// to connect immediately.
	nc.mu.Lock()
	nc.initc = true
	// The pool may change inside the loop iteration due to INFO protocol.
	for i := 0; i < len(nc.srvPool); i++ {
		nc.current = nc.srvPool[i]

		if err := nc.createConn(); err == nil {
			// This was moved out of processConnectInit() because
			// that function is now invoked from doReconnect() too.
			nc.setup()

			err = nc.processConnectInit()

			if err == nil {
				nc.srvPool[i].didConnect = true
				nc.srvPool[i].reconnects = 0
				returnedErr = nil
				break
			} else {
				returnedErr = err
				nc.mu.Unlock()
				nc.close(DISCONNECTED, false)
				nc.mu.Lock()
				nc.current = nil
			}
		} else {
			// Cancel out default connection refused, will trigger the
			// No servers error conditional
			if strings.Contains(err.Error(), "connection refused") {
				returnedErr = nil
			}
		}
	}
	nc.initc = false
	if returnedErr == nil && nc.status != CONNECTED {
		returnedErr = ErrNoServers
	}
	nc.mu.Unlock()
	return returnedErr
}
494382
func (p *connectionPoolImpl) Register(network string, address string) error {
	return p.pool.Register(network + " " + address)
}
1177948
func (cp *ConnectionPool) MaxCap() int64 {
	p := cp.pool()
	if p == nil {
		return 0
	}
	return p.MaxCap()
}
484977
func (f *Selectable) Fill(v interface{}, e error) error {
	f.m.Lock()
	if f.filled == 0 {
		f.val = v
		f.err = e
		atomic.StoreUint32(&f.filled, 1)
		w := f.wait
		f.wait = closed
		if w != nil {
			close(w)
		}
	}
	f.m.Unlock()
	return f.err
}
939005
func NewPool(config Config) *ConnectionPool {
	p := &ConnectionPool{
		Config: config,
		pool:   make(chan *Connection, config.Size),
	}
	return p
}
522410
func (c *Cluster) FillDefaults() error {
	// Topology support
	if c.Spec.Topology == nil {
		c.Spec.Topology = &TopologySpec{Masters: TopologyPublic, Nodes: TopologyPublic}
		c.Spec.Topology.DNS = &DNSSpec{Type: DNSTypePublic}
	}

	if c.Spec.Networking == nil {
		c.Spec.Networking = &NetworkingSpec{}
	}

	// TODO move this into networking.go :(
	if c.Spec.Networking.Classic != nil {
		// OK
	} else if c.Spec.Networking.Kubenet != nil {
		// OK
	} else if c.Spec.Networking.CNI != nil {
		// OK
	} else if c.Spec.Networking.External != nil {
		// OK
	} else if c.Spec.Networking.Kopeio != nil {
		// OK
	} else if c.Spec.Networking.Weave != nil {
		// OK
	} else if c.Spec.Networking.Flannel != nil {
		// OK
	} else if c.Spec.Networking.Calico != nil {
		// OK
	} else if c.Spec.Networking.Canal != nil {
		// OK
	} else if c.Spec.Networking.Kuberouter != nil {
		// OK
	} else if c.Spec.Networking.Romana != nil {
		// OK
	} else if c.Spec.Networking.AmazonVPC != nil {
		// OK
	} else if c.Spec.Networking.Cilium != nil {
		if c.Spec.Networking.Cilium.Version == "" {
			c.Spec.Networking.Cilium.Version = CiliumDefaultVersion
		}
		// OK
	} else if c.Spec.Networking.LyftVPC != nil {
		// OK
	} else {
		// No networking model selected; choose Kubenet
		c.Spec.Networking.Kubenet = &KubenetNetworkingSpec{}
	}

	if c.Spec.Channel == "" {
		c.Spec.Channel = DefaultChannel
	}

	if c.ObjectMeta.Name == "" {
		return fmt.Errorf("cluster Name not set in FillDefaults")
	}

	if c.Spec.MasterInternalName == "" {
		c.Spec.MasterInternalName = "api.internal." + c.ObjectMeta.Name
	}

	if c.Spec.MasterPublicName == "" {
		c.Spec.MasterPublicName = "api." + c.ObjectMeta.Name
	}

	return nil
}
1189343
func (c *Client) Connect(config *Config) (ConnectFuture, error) {
	if config == nil {
		panic("no config specified")
	}

	c.mutex.Lock()
	defer c.mutex.Unlock()

	// check if already connecting
	if atomic.LoadUint32(&c.state) >= clientConnecting {
		return nil, ErrClientAlreadyConnecting
	}

	// save config
	c.config = config

	// parse url
	urlParts, err := url.ParseRequestURI(config.BrokerURL)
	if err != nil {
		return nil, err
	}

	// check client id
	if !config.CleanSession && config.ClientID == "" {
		return nil, ErrClientMissingID
	}

	// parse keep alive
	keepAlive, err := time.ParseDuration(config.KeepAlive)
	if err != nil {
		return nil, err
	}

	// allocate and initialize tracker
	c.keepAlive = keepAlive
	c.tracker = NewTracker(keepAlive)

	// dial broker (with custom dialer if present)
	if config.Dialer != nil {
		c.conn, err = config.Dialer.Dial(config.BrokerURL)
		if err != nil {
			return nil, err
		}
	} else {
		c.conn, err = transport.Dial(config.BrokerURL)
		if err != nil {
			return nil, err
		}
	}

	// set to connecting as from this point the client cannot be reused
	atomic.StoreUint32(&c.state, clientConnecting)

	// from now on the connection has been used and we have to close the
	// connection and cleanup on any subsequent error

	// save clean
	c.clean = config.CleanSession

	// reset store
	if c.clean {
		err = c.Session.Reset()
		if err != nil {
			return nil, c.cleanup(err, true, false)
		}
	}

	// allocate packet
	connect := packet.NewConnect()
	connect.ClientID = config.ClientID
	connect.KeepAlive = uint16(keepAlive.Seconds())
	connect.CleanSession = config.CleanSession

	// check for credentials
	if urlParts.User != nil {
		connect.Username = urlParts.User.Username()
		connect.Password, _ = urlParts.User.Password()
	}

	// set will
	connect.Will = config.WillMessage

	// create new ConnectFuture
	c.connectFuture = future.New()

	// send connect packet
	err = c.send(connect, false)
	if err != nil {
		return nil, c.cleanup(err, false, false)
	}

	// start process routine
	c.tomb.Go(c.processor)

	// wrap future
	wrappedFuture := &connectFuture{c.connectFuture}

	return wrappedFuture, nil
}
865470
func (cp *connectionPool) connCloser() {
	var connCount uint64

	t := time.NewTimer(ConnCloserInterval)
	defer t.Stop()

	for {
		connCount = cp.connCount

		// we don't exist anymore! bail out!
		select {
		case <-cp.bailOut:
			return
		case <-t.C:
		}
		t.Reset(ConnCloserInterval)

		// no overflow connections open or sustained requests for connections
		// nothing to do until the next cycle
		if len(cp.connections) <= cp.poolSize ||
			ConnCloserInterval/ConnPoolAvailWaitTime < time.Duration(cp.connCount-connCount) {
			continue
		}

		// close overflow connections now that they are not needed
		for c := range cp.connections {
			select {
			case <-cp.bailOut:
				return
			default:
			}

			// bail out if close did not work out
			if !cp.connCleanup(c) {
				return
			}
			if len(cp.connections) <= cp.poolSize {
				break
			}
		}
	}
}