From f35339c74ecdf706b926c00170aad574b46a07d5 Mon Sep 17 00:00:00 2001 From: u5surf Date: Sun, 13 Mar 2022 22:25:06 +0900 Subject: [PATCH] Add connection pool queuing strategies in HostClient. * At first, we implement LIFO(conventional) and FIFO which indicate in #1236 * Change default strategy FIFO --- client.go | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/client.go b/client.go index b36ca40824..2ac54d897b 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. Can be either LIFO or FIFO (default). + 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 your HostClient configuration. + ErrConnPoolStrategyNotImpl = errors.New("connection pool strategy is not implement") ) type timeoutError struct{} @@ -1544,10 +1559,20 @@ 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] + copy(c.conns, c.conns[1:]) + c.conns[n-1] = nil + c.conns = c.conns[:n-1] + default: + return nil, ErrConnPoolStrategyNotImpl + } } c.connsLock.Unlock()