Skip to content

Commit

Permalink
Merge pull request redis#611 from go-redis/fix/pubsub-deadlock
Browse files Browse the repository at this point in the history
Fix PubSub.Subscribe deadlock
  • Loading branch information
vmihailenco authored Aug 1, 2017
2 parents 2fb3f0e + dbcf95c commit a8ee441
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 13 deletions.
26 changes: 13 additions & 13 deletions pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,19 @@ func (c *PubSub) _subscribe(cn *pool.Conn, redisCmd string, channels ...string)
return writeCmd(cn, cmd)
}

func (c *PubSub) putConn(cn *pool.Conn, err error) {
if !internal.IsBadConn(err, true) {
return
}

func (c *PubSub) releaseConn(cn *pool.Conn, err error) {
c.mu.Lock()
if c.cn == cn {
_ = c.releaseConn()
}
c._releaseConn(cn, err)
c.mu.Unlock()
}

func (c *PubSub) releaseConn() error {
func (c *PubSub) _releaseConn(cn *pool.Conn, err error) {
if internal.IsBadConn(err, true) && c.cn == cn {
_ = c.closeTheCn()
}
}

func (c *PubSub) closeTheCn() error {
err := c.closeConn(c.cn)
c.cn = nil
return err
Expand All @@ -116,7 +116,7 @@ func (c *PubSub) Close() error {
c.closed = true

if c.cn != nil {
return c.releaseConn()
return c.closeTheCn()
}
return nil
}
Expand Down Expand Up @@ -168,7 +168,7 @@ func (c *PubSub) subscribe(redisCmd string, channels ...string) error {
}

err = c._subscribe(cn, redisCmd, channels...)
c.putConn(cn, err)
c._releaseConn(cn, err)
return err
}

Expand All @@ -186,7 +186,7 @@ func (c *PubSub) Ping(payload ...string) error {

cn.SetWriteTimeout(c.opt.WriteTimeout)
err = writeCmd(cn, cmd)
c.putConn(cn, err)
c.releaseConn(cn, err)
return err
}

Expand Down Expand Up @@ -279,7 +279,7 @@ func (c *PubSub) ReceiveTimeout(timeout time.Duration) (interface{}, error) {

cn.SetReadTimeout(timeout)
err = c.cmd.readReply(cn)
c.putConn(cn, err)
c.releaseConn(cn, err)
if err != nil {
return nil, err
}
Expand Down
16 changes: 16 additions & 0 deletions pubsub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,22 @@ var _ = Describe("PubSub", func() {
Expect(stats.Hits).To(Equal(uint32(1)))
})

It("returns an error when subscribe fails", func() {
pubsub := client.Subscribe()
defer pubsub.Close()

pubsub.SetNetConn(&badConn{
readErr: io.EOF,
writeErr: io.EOF,
})

err := pubsub.Subscribe("mychannel")
Expect(err).To(MatchError("EOF"))

err = pubsub.Subscribe("mychannel")
Expect(err).NotTo(HaveOccurred())
})

expectReceiveMessageOnError := func(pubsub *redis.PubSub) {
pubsub.SetNetConn(&badConn{
readErr: io.EOF,
Expand Down

0 comments on commit a8ee441

Please sign in to comment.