From 029065eb68819816ef5da0343397d4cefbba7ad0 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Mon, 13 Jul 2015 13:45:37 +0300 Subject: [PATCH] Fix nil pool on read timeout. Fixes #135. --- conn.go | 5 ++--- pool.go | 34 ++++++++++++++++++++-------------- redis_test.go | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/conn.go b/conn.go index bf104d9..9dc2ede 100644 --- a/conn.go +++ b/conn.go @@ -42,9 +42,8 @@ func (cn *conn) init(opt *Options) error { return nil } - // Use connection to connect to redis - pool := newSingleConnPool(nil, false) - pool.SetConn(cn) + // Use connection to connect to Redis. + pool := newSingleConnPoolConn(cn) // Client is not closed because we want to reuse underlying connection. client := newClient(opt, pool) diff --git a/pool.go b/pool.go index 714cbe5..71ac456 100644 --- a/pool.go +++ b/pool.go @@ -329,13 +329,10 @@ func newSingleConnPool(pool pool, reusable bool) *singleConnPool { } } -func (p *singleConnPool) SetConn(cn *conn) { - p.mx.Lock() - if p.cn != nil { - panic("p.cn != nil") +func newSingleConnPoolConn(cn *conn) *singleConnPool { + return &singleConnPool{ + cn: cn, } - p.cn = cn - p.mx.Unlock() } func (p *singleConnPool) First() *conn { @@ -365,6 +362,14 @@ func (p *singleConnPool) Get() (*conn, error) { return p.cn, nil } +func (p *singleConnPool) put() (err error) { + if p.pool != nil { + err = p.pool.Put(p.cn) + } + p.cn = nil + return err +} + func (p *singleConnPool) Put(cn *conn) error { defer p.mx.Unlock() p.mx.Lock() @@ -377,6 +382,14 @@ func (p *singleConnPool) Put(cn *conn) error { return nil } +func (p *singleConnPool) remove() (err error) { + if p.pool != nil { + err = p.pool.Remove(p.cn) + } + p.cn = nil + return err +} + func (p *singleConnPool) Remove(cn *conn) error { defer p.mx.Unlock() p.mx.Lock() @@ -392,12 +405,6 @@ func (p *singleConnPool) Remove(cn *conn) error { return p.remove() } -func (p *singleConnPool) remove() error { - err := p.pool.Remove(p.cn) - p.cn = nil - return err -} - func (p *singleConnPool) Len() int { defer p.mx.Unlock() p.mx.Lock() @@ -426,8 +433,7 @@ func (p *singleConnPool) Close() error { var err error if p.cn != nil { if p.reusable { - err = p.pool.Put(p.cn) - p.cn = nil + err = p.put() } else { err = p.remove() } diff --git a/redis_test.go b/redis_test.go index ac5ee7c..3c0d635 100644 --- a/redis_test.go +++ b/redis_test.go @@ -134,6 +134,20 @@ var _ = Describe("Client", func() { Expect(db1.FlushDb().Err()).NotTo(HaveOccurred()) }) + It("should support DB selection with read timeout (issue #135)", func() { + for i := 0; i < 100; i++ { + db1 := redis.NewClient(&redis.Options{ + Addr: redisAddr, + DB: 1, + ReadTimeout: time.Nanosecond, + }) + + err := db1.Ping().Err() + Expect(err).To(HaveOccurred()) + Expect(err.(net.Error).Timeout()).To(BeTrue()) + } + }) + It("should retry command on network error", func() { Expect(client.Close()).NotTo(HaveOccurred())