From ce40cd942a72c4a93f9025047e6fd3f510700ab3 Mon Sep 17 00:00:00 2001 From: ktaekwon000 Date: Fri, 16 Jul 2021 11:58:01 +0800 Subject: [PATCH] Allow FIFO pool in redis client (#1820) * Initial commit for FIFO pool * Change PoolType string to PoolFIFO bool * Remove redundant type * add PoolFIFO option to all clients Signed-off-by: monkey92t Co-authored-by: Kim Tae Kwon Co-authored-by: monkey92t --- cluster.go | 4 ++++ internal/pool/pool.go | 17 +++++++++++++---- options.go | 5 +++++ ring.go | 4 ++++ sentinel.go | 6 ++++++ universal.go | 6 ++++++ 6 files changed, 38 insertions(+), 4 deletions(-) diff --git a/cluster.go b/cluster.go index 49b2d37bd..9690f88a8 100644 --- a/cluster.go +++ b/cluster.go @@ -68,6 +68,9 @@ type ClusterOptions struct { ReadTimeout time.Duration WriteTimeout time.Duration + // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). + PoolFIFO bool + // PoolSize applies per cluster node and not for the whole cluster. PoolSize int MinIdleConns int @@ -146,6 +149,7 @@ func (opt *ClusterOptions) clientOptions() *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, + PoolFIFO: opt.PoolFIFO, PoolSize: opt.PoolSize, MinIdleConns: opt.MinIdleConns, MaxConnAge: opt.MaxConnAge, diff --git a/internal/pool/pool.go b/internal/pool/pool.go index a8f0a6d4e..91b55e466 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -57,6 +57,7 @@ type Options struct { Dialer func(context.Context) (net.Conn, error) OnClose func(*Conn) error + PoolFIFO bool PoolSize int MinIdleConns int MaxConnAge time.Duration @@ -308,13 +309,21 @@ func (p *ConnPool) freeTurn() { } func (p *ConnPool) popIdle() *Conn { - if len(p.idleConns) == 0 { + n := len(p.idleConns) + if n == 0 { return nil } - idx := len(p.idleConns) - 1 - cn := p.idleConns[idx] - p.idleConns = p.idleConns[:idx] + var cn *Conn + if p.opt.PoolFIFO { + cn = p.idleConns[0] + copy(p.idleConns, p.idleConns[1:]) + p.idleConns = p.idleConns[:n-1] + } else { + idx := n - 1 + cn = p.idleConns[idx] + p.idleConns = p.idleConns[:idx] + } p.idleConnsLen-- p.checkMinIdleConns() return cn diff --git a/options.go b/options.go index 8bbc27b82..5d39bf049 100644 --- a/options.go +++ b/options.go @@ -76,6 +76,10 @@ type Options struct { // Default is ReadTimeout. WriteTimeout time.Duration + // Type of connection pool. + // true for FIFO pool, false for LIFO pool. + // Note that fifo has higher overhead compared to lifo. + PoolFIFO bool // Maximum number of socket connections. // Default is 10 connections per every available CPU as reported by runtime.GOMAXPROCS. PoolSize int @@ -291,6 +295,7 @@ func newConnPool(opt *Options) *pool.ConnPool { Dialer: func(ctx context.Context) (net.Conn, error) { return opt.Dialer(ctx, opt.Network, opt.Addr) }, + PoolFIFO: opt.PoolFIFO, PoolSize: opt.PoolSize, MinIdleConns: opt.MinIdleConns, MaxConnAge: opt.MaxConnAge, diff --git a/ring.go b/ring.go index 34d05f35a..5e35b6bb6 100644 --- a/ring.go +++ b/ring.go @@ -78,6 +78,9 @@ type RingOptions struct { ReadTimeout time.Duration WriteTimeout time.Duration + // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). + PoolFIFO bool + PoolSize int MinIdleConns int MaxConnAge time.Duration @@ -138,6 +141,7 @@ func (opt *RingOptions) clientOptions() *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, + PoolFIFO: opt.PoolFIFO, PoolSize: opt.PoolSize, MinIdleConns: opt.MinIdleConns, MaxConnAge: opt.MaxConnAge, diff --git a/sentinel.go b/sentinel.go index ca2e088a7..7b53fd4f5 100644 --- a/sentinel.go +++ b/sentinel.go @@ -57,6 +57,9 @@ type FailoverOptions struct { ReadTimeout time.Duration WriteTimeout time.Duration + // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). + PoolFIFO bool + PoolSize int MinIdleConns int MaxConnAge time.Duration @@ -86,6 +89,7 @@ func (opt *FailoverOptions) clientOptions() *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, + PoolFIFO: opt.PoolFIFO, PoolSize: opt.PoolSize, PoolTimeout: opt.PoolTimeout, IdleTimeout: opt.IdleTimeout, @@ -115,6 +119,7 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, + PoolFIFO: opt.PoolFIFO, PoolSize: opt.PoolSize, PoolTimeout: opt.PoolTimeout, IdleTimeout: opt.IdleTimeout, @@ -146,6 +151,7 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, + PoolFIFO: opt.PoolFIFO, PoolSize: opt.PoolSize, PoolTimeout: opt.PoolTimeout, IdleTimeout: opt.IdleTimeout, diff --git a/universal.go b/universal.go index bb5f8b616..1e962ab3b 100644 --- a/universal.go +++ b/universal.go @@ -35,6 +35,9 @@ type UniversalOptions struct { ReadTimeout time.Duration WriteTimeout time.Duration + // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). + PoolFIFO bool + PoolSize int MinIdleConns int MaxConnAge time.Duration @@ -83,6 +86,7 @@ func (o *UniversalOptions) Cluster() *ClusterOptions { DialTimeout: o.DialTimeout, ReadTimeout: o.ReadTimeout, WriteTimeout: o.WriteTimeout, + PoolFIFO: o.PoolFIFO, PoolSize: o.PoolSize, MinIdleConns: o.MinIdleConns, MaxConnAge: o.MaxConnAge, @@ -120,6 +124,7 @@ func (o *UniversalOptions) Failover() *FailoverOptions { ReadTimeout: o.ReadTimeout, WriteTimeout: o.WriteTimeout, + PoolFIFO: o.PoolFIFO, PoolSize: o.PoolSize, MinIdleConns: o.MinIdleConns, MaxConnAge: o.MaxConnAge, @@ -155,6 +160,7 @@ func (o *UniversalOptions) Simple() *Options { ReadTimeout: o.ReadTimeout, WriteTimeout: o.WriteTimeout, + PoolFIFO: o.PoolFIFO, PoolSize: o.PoolSize, MinIdleConns: o.MinIdleConns, MaxConnAge: o.MaxConnAge,