diff --git a/client.go b/client.go index b36ca40824..121744a495 100644 --- a/client.go +++ b/client.go @@ -618,6 +618,14 @@ type RetryIfFunc func(request *Request) bool // TransportFunc wraps every request/response. type TransportFunc func(*Request, *Response) error +// ConnPoolStrategyType define strategy of connection pool enqueue/dequeue +type ConnPoolStrategyType int + +const ( + FIFO ConnPoolStrategyType = iota + LIFO +) + // HostClient balances http requests among hosts listed in Addr. // // HostClient may be used for balancing load among multiple upstream hosts. @@ -772,6 +780,9 @@ type HostClient struct { // Transport defines a transport-like mechanism that wraps every request/response. Transport TransportFunc + // Connection pool strategy determines whether LIFO or FIFO storategy for connection pool + ConnPoolStrategy ConnPoolStrategyType + clientName atomic.Value lastUseTime uint32 @@ -1497,6 +1508,10 @@ var ( // to broken server. ErrConnectionClosed = errors.New("the server closed connection before returning the first response byte. " + "Make sure the server returns 'Connection: close' response header before closing the connection") + + // ErrConnPoolStrategyNotImpl is returned when HostClient.ConnPoolStrategy is not implement yet. + // If you see this error, then you need to check HostClient configuration once. + ErrConnPoolStrategyNotImpl = errors.New("connection pool strategy is not implement") ) type timeoutError struct{} @@ -1544,10 +1559,19 @@ func (c *HostClient) acquireConn(reqTimeout time.Duration, connectionClose bool) } } } else { - n-- - cc = c.conns[n] - c.conns[n] = nil - c.conns = c.conns[:n] + switch c.ConnPoolStrategy { + case LIFO: + n-- + cc = c.conns[n] + c.conns[n] = nil + c.conns = c.conns[:n] + case FIFO: + cc = c.conns[0] + c.conns[0] = nil + c.conns = c.conns[1:] + default: + return nil, ErrConnPoolStrategyNotImpl + } } c.connsLock.Unlock()