Fix nil pool on read timeout. Fixes #135.

This commit is contained in:
Vladimir Mihailenco 2015-07-13 13:45:37 +03:00
parent 7baacea8fb
commit 029065eb68
3 changed files with 36 additions and 17 deletions

View File

@ -42,9 +42,8 @@ func (cn *conn) init(opt *Options) error {
return nil return nil
} }
// Use connection to connect to redis // Use connection to connect to Redis.
pool := newSingleConnPool(nil, false) pool := newSingleConnPoolConn(cn)
pool.SetConn(cn)
// Client is not closed because we want to reuse underlying connection. // Client is not closed because we want to reuse underlying connection.
client := newClient(opt, pool) client := newClient(opt, pool)

34
pool.go
View File

@ -329,13 +329,10 @@ func newSingleConnPool(pool pool, reusable bool) *singleConnPool {
} }
} }
func (p *singleConnPool) SetConn(cn *conn) { func newSingleConnPoolConn(cn *conn) *singleConnPool {
p.mx.Lock() return &singleConnPool{
if p.cn != nil { cn: cn,
panic("p.cn != nil")
} }
p.cn = cn
p.mx.Unlock()
} }
func (p *singleConnPool) First() *conn { func (p *singleConnPool) First() *conn {
@ -365,6 +362,14 @@ func (p *singleConnPool) Get() (*conn, error) {
return p.cn, nil 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 { func (p *singleConnPool) Put(cn *conn) error {
defer p.mx.Unlock() defer p.mx.Unlock()
p.mx.Lock() p.mx.Lock()
@ -377,6 +382,14 @@ func (p *singleConnPool) Put(cn *conn) error {
return nil 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 { func (p *singleConnPool) Remove(cn *conn) error {
defer p.mx.Unlock() defer p.mx.Unlock()
p.mx.Lock() p.mx.Lock()
@ -392,12 +405,6 @@ func (p *singleConnPool) Remove(cn *conn) error {
return p.remove() return p.remove()
} }
func (p *singleConnPool) remove() error {
err := p.pool.Remove(p.cn)
p.cn = nil
return err
}
func (p *singleConnPool) Len() int { func (p *singleConnPool) Len() int {
defer p.mx.Unlock() defer p.mx.Unlock()
p.mx.Lock() p.mx.Lock()
@ -426,8 +433,7 @@ func (p *singleConnPool) Close() error {
var err error var err error
if p.cn != nil { if p.cn != nil {
if p.reusable { if p.reusable {
err = p.pool.Put(p.cn) err = p.put()
p.cn = nil
} else { } else {
err = p.remove() err = p.remove()
} }

View File

@ -134,6 +134,20 @@ var _ = Describe("Client", func() {
Expect(db1.FlushDb().Err()).NotTo(HaveOccurred()) 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() { It("should retry command on network error", func() {
Expect(client.Close()).NotTo(HaveOccurred()) Expect(client.Close()).NotTo(HaveOccurred())