@@ -549,26 +549,50 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) {
549
549
}
550
550
}
551
551
552
+ var masterAddr string
553
+ var wg sync.WaitGroup
554
+ var once sync.Once
555
+ done := make (chan struct {})
556
+
552
557
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
+ })
554
581
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
560
582
}
561
- internal .Logger .Printf (ctx , "sentinel: GetMasterAddrByName master=%q failed: %s" ,
562
- c .opt .MasterName , err )
563
- continue
564
- }
565
583
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 )
569
585
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
572
596
}
573
597
574
598
return "" , errors .New ("redis: all sentinels specified in configuration are unreachable" )
0 commit comments