Skip to content

Commit

Permalink
Update conn.UsedAt on Read/Write. Fixes redis#263.
Browse files Browse the repository at this point in the history
  • Loading branch information
vmihailenco committed Mar 2, 2016
1 parent a4e4d1d commit 78d40d5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
14 changes: 8 additions & 6 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import (
const defaultBufSize = 4096

var (
zeroTime = time.Time{}
noTimeout = time.Time{}
)

type conn struct {
netcn net.Conn
rd *bufio.Reader
buf []byte

usedAt time.Time
UsedAt time.Time
ReadTimeout time.Duration
WriteTimeout time.Duration
}
Expand Down Expand Up @@ -76,19 +76,21 @@ func (cn *conn) writeCmds(cmds ...Cmder) error {
}

func (cn *conn) Read(b []byte) (int, error) {
cn.UsedAt = time.Now()
if cn.ReadTimeout != 0 {
cn.netcn.SetReadDeadline(time.Now().Add(cn.ReadTimeout))
cn.netcn.SetReadDeadline(cn.UsedAt.Add(cn.ReadTimeout))
} else {
cn.netcn.SetReadDeadline(zeroTime)
cn.netcn.SetReadDeadline(noTimeout)
}
return cn.netcn.Read(b)
}

func (cn *conn) Write(b []byte) (int, error) {
cn.UsedAt = time.Now()
if cn.WriteTimeout != 0 {
cn.netcn.SetWriteDeadline(time.Now().Add(cn.WriteTimeout))
cn.netcn.SetWriteDeadline(cn.UsedAt.Add(cn.WriteTimeout))
} else {
cn.netcn.SetWriteDeadline(zeroTime)
cn.netcn.SetWriteDeadline(noTimeout)
}
return cn.netcn.Write(b)
}
Expand Down
5 changes: 1 addition & 4 deletions pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (p *connPool) closed() bool {
}

func (p *connPool) isIdle(cn *conn) bool {
return p.opt.getIdleTimeout() > 0 && time.Since(cn.usedAt) > p.opt.getIdleTimeout()
return p.opt.getIdleTimeout() > 0 && time.Since(cn.UsedAt) > p.opt.getIdleTimeout()
}

// First returns first non-idle connection from the pool or nil if
Expand Down Expand Up @@ -275,9 +275,6 @@ func (p *connPool) Put(cn *conn) error {
Logger.Print(err)
return p.Remove(cn, err)
}
if p.opt.getIdleTimeout() > 0 {
cn.usedAt = time.Now()
}
p.freeConns <- cn
return nil
}
Expand Down
29 changes: 22 additions & 7 deletions redis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,41 +55,39 @@ var _ = Describe("Client", func() {
It("should close", func() {
Expect(client.Close()).NotTo(HaveOccurred())
err := client.Ping().Err()
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError("redis: client is closed"))
})

It("should close pubsub without closing the connection", func() {
It("should close pubsub without closing the client", func() {
pubsub := client.PubSub()
Expect(pubsub.Close()).NotTo(HaveOccurred())

_, err := pubsub.Receive()
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError("redis: client is closed"))
Expect(client.Ping().Err()).NotTo(HaveOccurred())
})

It("should close multi without closing the connection", func() {
It("should close multi without closing the client", func() {
multi := client.Multi()
Expect(multi.Close()).NotTo(HaveOccurred())

_, err := multi.Exec(func() error {
multi.Ping()
return nil
})
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError("redis: client is closed"))

Expect(client.Ping().Err()).NotTo(HaveOccurred())
})

It("should close pipeline without closing the connection", func() {
It("should close pipeline without closing the client", func() {
pipeline := client.Pipeline()
Expect(pipeline.Close()).NotTo(HaveOccurred())

pipeline.Ping()
_, err := pipeline.Exec()
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError("redis: client is closed"))

Expect(client.Ping().Err()).NotTo(HaveOccurred())
})

Expand Down Expand Up @@ -171,6 +169,23 @@ var _ = Describe("Client", func() {
err = client.Ping().Err()
Expect(err).NotTo(HaveOccurred())
})

It("should maintain conn.UsedAt", func() {
cn, _, err := client.Pool().Get()
Expect(err).NotTo(HaveOccurred())
Expect(cn.UsedAt).To(BeZero())

err = client.Pool().Put(cn)
Expect(err).NotTo(HaveOccurred())
Expect(cn.UsedAt).To(BeZero())

err = client.Ping().Err()
Expect(err).NotTo(HaveOccurred())

cn = client.Pool().First()
Expect(cn).NotTo(BeNil())
Expect(cn.UsedAt).To(BeTemporally("~", time.Now()))
})
})

//------------------------------------------------------------------------------
Expand Down

0 comments on commit 78d40d5

Please sign in to comment.