Skip to content

Commit 4afa84c

Browse files
committed
Fix sentinel leak
1 parent 2cd577a commit 4afa84c

File tree

1 file changed

+41
-34
lines changed

1 file changed

+41
-34
lines changed

sentinel.go

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,19 @@ func (c *sentinelFailover) Close() error {
301301
return nil
302302
}
303303

304+
func (c *sentinelFailover) closeSentinel() error {
305+
firstErr := c.pubsub.Close()
306+
c.pubsub = nil
307+
308+
err := c.sentinel.Close()
309+
if err != nil && firstErr == nil {
310+
firstErr = err
311+
}
312+
c.sentinel = nil
313+
314+
return firstErr
315+
}
316+
304317
func (c *sentinelFailover) Pool() *pool.ConnPool {
305318
c.poolOnce.Do(func() {
306319
opt := *c.opt
@@ -331,14 +344,28 @@ func (c *sentinelFailover) MasterAddr() (string, error) {
331344
}
332345

333346
func (c *sentinelFailover) masterAddr() (string, error) {
334-
addr := c.getMasterAddr()
335-
if addr != "" {
336-
return addr, nil
347+
c.mu.RLock()
348+
sentinel := c.sentinel
349+
c.mu.RUnlock()
350+
351+
if sentinel != nil {
352+
addr := c.getMasterAddr(sentinel)
353+
if addr != "" {
354+
return addr, nil
355+
}
337356
}
338357

339358
c.mu.Lock()
340359
defer c.mu.Unlock()
341360

361+
if c.sentinel != nil {
362+
addr := c.getMasterAddr(c.sentinel)
363+
if addr != "" {
364+
return addr, nil
365+
}
366+
_ = c.closeSentinel()
367+
}
368+
342369
for i, sentinelAddr := range c.sentinelAddrs {
343370
sentinel := NewSentinelClient(&Options{
344371
Addr: sentinelAddr,
@@ -378,27 +405,13 @@ func (c *sentinelFailover) masterAddr() (string, error) {
378405
return "", errors.New("redis: all sentinels are unreachable")
379406
}
380407

381-
func (c *sentinelFailover) getMasterAddr() string {
382-
c.mu.RLock()
383-
sentinel := c.sentinel
384-
c.mu.RUnlock()
385-
386-
if sentinel == nil {
387-
return ""
388-
}
389-
408+
func (c *sentinelFailover) getMasterAddr(sentinel *SentinelClient) string {
390409
addr, err := sentinel.GetMasterAddrByName(c.masterName).Result()
391410
if err != nil {
392411
internal.Logger.Printf("sentinel: GetMasterAddrByName name=%q failed: %s",
393412
c.masterName, err)
394-
c.mu.Lock()
395-
if c.sentinel == sentinel {
396-
_ = c.closeSentinel()
397-
}
398-
c.mu.Unlock()
399413
return ""
400414
}
401-
402415
return net.JoinHostPort(addr[0], addr[1])
403416
}
404417

@@ -413,6 +426,10 @@ func (c *sentinelFailover) switchMaster(addr string) {
413426
c.mu.Lock()
414427
defer c.mu.Unlock()
415428

429+
if c._masterAddr == addr {
430+
return
431+
}
432+
416433
internal.Logger.Printf("sentinel: new master=%q addr=%q",
417434
c.masterName, addr)
418435
_ = c.Pool().Filter(func(cn *pool.Conn) bool {
@@ -422,28 +439,18 @@ func (c *sentinelFailover) switchMaster(addr string) {
422439
}
423440

424441
func (c *sentinelFailover) setSentinel(sentinel *SentinelClient) {
425-
c.discoverSentinels(sentinel)
442+
if c.sentinel != nil {
443+
panic("not reached")
444+
}
426445
c.sentinel = sentinel
446+
c.discoverSentinels()
427447

428448
c.pubsub = sentinel.Subscribe("+switch-master")
429449
go c.listen(c.pubsub)
430450
}
431451

432-
func (c *sentinelFailover) closeSentinel() error {
433-
firstErr := c.pubsub.Close()
434-
c.pubsub = nil
435-
436-
err := c.sentinel.Close()
437-
if err != nil && firstErr == nil {
438-
firstErr = err
439-
}
440-
c.sentinel = nil
441-
442-
return firstErr
443-
}
444-
445-
func (c *sentinelFailover) discoverSentinels(sentinel *SentinelClient) {
446-
sentinels, err := sentinel.Sentinels(c.masterName).Result()
452+
func (c *sentinelFailover) discoverSentinels() {
453+
sentinels, err := c.sentinel.Sentinels(c.masterName).Result()
447454
if err != nil {
448455
internal.Logger.Printf("sentinel: Sentinels master=%q failed: %s", c.masterName, err)
449456
return

0 commit comments

Comments
 (0)