@@ -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