Skip to content

Commit 7e63d65

Browse files
authored
bug: fix Query sentinel changed to concurrent query to avoid context exhaustion
1 parent 1ed936e commit 7e63d65

File tree

1 file changed

+39
-15
lines changed

1 file changed

+39
-15
lines changed

sentinel.go

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -549,26 +549,50 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) {
549549
}
550550
}
551551

552+
var masterAddr string
553+
var wg sync.WaitGroup
554+
var once sync.Once
555+
done := make(chan struct{})
556+
552557
for i, sentinelAddr := range c.sentinelAddrs {
553-
sentinel := NewSentinelClient(c.opt.sentinelOptions(sentinelAddr))
558+
wg.Add(1)
559+
go func(i int, addr string) {
560+
defer wg.Done()
561+
select {
562+
case <-done:
563+
default:
564+
sentinelCli := NewSentinelClient(c.opt.sentinelOptions(addr))
565+
addrVal, err := sentinelCli.GetMasterAddrByName(ctx, c.opt.MasterName).Result()
566+
if err != nil {
567+
internal.Logger.Printf(ctx, "sentinel: GetMasterAddrByName addr=%s, master=%q failed: %s",
568+
addr, c.opt.MasterName, err)
569+
_ = sentinelCli.Close()
570+
return
571+
}
572+
internal.Logger.Printf(ctx, "get addr %s master res %v", addr, masterAddr)
573+
once.Do(func() {
574+
// Push working sentinel to the top.
575+
masterAddr = net.JoinHostPort(addrVal[0], addrVal[1])
576+
c.sentinelAddrs[0], c.sentinelAddrs[i] = c.sentinelAddrs[i], c.sentinelAddrs[0]
577+
c.setSentinel(ctx, sentinelCli)
578+
close(done)
579+
580+
})
554581

555-
masterAddr, err := sentinel.GetMasterAddrByName(ctx, c.opt.MasterName).Result()
556-
if err != nil {
557-
_ = sentinel.Close()
558-
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
559-
return "", err
560582
}
561-
internal.Logger.Printf(ctx, "sentinel: GetMasterAddrByName master=%q failed: %s",
562-
c.opt.MasterName, err)
563-
continue
564-
}
565583

566-
// Push working sentinel to the top.
567-
c.sentinelAddrs[0], c.sentinelAddrs[i] = c.sentinelAddrs[i], c.sentinelAddrs[0]
568-
c.setSentinel(ctx, sentinel)
584+
}(i, sentinelAddr)
569585

570-
addr := net.JoinHostPort(masterAddr[0], masterAddr[1])
571-
return addr, nil
586+
}
587+
go func() {
588+
wg.Wait()
589+
once.Do(func() {
590+
close(done)
591+
})
592+
}()
593+
<-done
594+
if masterAddr != "" {
595+
return masterAddr, nil
572596
}
573597

574598
return "", errors.New("redis: all sentinels specified in configuration are unreachable")

0 commit comments

Comments
 (0)