@@ -806,15 +806,27 @@ func (c *sentinelFailover) RandomReplicaAddr(ctx context.Context) (string, error
806806}
807807
808808func (c * sentinelFailover ) MasterAddr (ctx context.Context ) (string , error ) {
809- c .mu .Lock ()
810- defer c .mu .Unlock ()
809+ c .mu .RLock ()
810+ sentinel := c .sentinel
811+ c .mu .RUnlock ()
811812
812- // short circuit
813- if c .sentinel == nil && len (c .sentinelAddrs ) == 0 {
814- return "" , errors .New ("redis: either of sentinel client or sentinels address must be configured" )
813+ if sentinel != nil {
814+ addr , err := c .getMasterAddr (ctx , sentinel )
815+ if err != nil {
816+ if errors .Is (err , context .Canceled ) || errors .Is (err , context .DeadlineExceeded ) {
817+ return "" , err
818+ }
819+ // Continue on other errors
820+ internal .Logger .Printf (ctx , "sentinel: GetMasterAddrByName name=%q failed: %s" ,
821+ c .opt .MasterName , err )
822+ } else {
823+ return addr , nil
824+ }
815825 }
816826
817- // use existing sentinel, if provided, to get master addr
827+ c .mu .Lock ()
828+ defer c .mu .Unlock ()
829+
818830 if c .sentinel != nil {
819831 addr , err := c .getMasterAddr (ctx , c .sentinel )
820832 if err != nil {
@@ -830,7 +842,6 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) {
830842 }
831843 }
832844
833- // fallback to querying sentinels in configuration
834845 // short circuit if no sentinels configured
835846 if len (c .sentinelAddrs ) == 0 {
836847 return "" , errors .New ("redis: no sentinels configured" )
@@ -846,24 +857,11 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) {
846857 ctx , cancel := context .WithCancel (ctx )
847858 defer cancel ()
848859
849- // track all created sentinel clients for cleanup
850- sentinelClients := make ([]* SentinelClient , len (c .sentinelAddrs ))
851- var selectedIdx = - 1
852- defer func () {
853- // Close all unused sentinel clients
854- for i , cli := range sentinelClients {
855- if cli != nil && i != selectedIdx {
856- _ = cli .Close ()
857- }
858- }
859- }()
860-
861860 for i , sentinelAddr := range c .sentinelAddrs {
862861 wg .Add (1 )
863862 go func (i int , addr string ) {
864863 defer wg .Done ()
865864 sentinelCli := NewSentinelClient (c .opt .sentinelOptions (addr ))
866- sentinelClients [i ] = sentinelCli
867865 addrVal , err := sentinelCli .GetMasterAddrByName (ctx , c .opt .MasterName ).Result ()
868866 if err != nil {
869867 internal .Logger .Printf (ctx , "sentinel: GetMasterAddrByName addr=%s, master=%q failed: %s" ,
@@ -872,40 +870,26 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) {
872870 errCh <- err
873871 return
874872 }
875- var shouldCancel bool
876873 once .Do (func () {
877- if len (addrVal ) < 2 {
878- internal .Logger .Printf (ctx , "sentinel: GetMasterAddrByName addr=%s, master=%q returned insufficient data: %v" , addr , c .opt .MasterName , addrVal )
879- _ = sentinelCli .Close ()
880- errCh <- fmt .Errorf ("redis: insufficient master address data from sentinel: %v" , addrVal )
881- return
882- }
883874 masterAddr = net .JoinHostPort (addrVal [0 ], addrVal [1 ])
884875 // Push working sentinel to the top
885876 c .sentinelAddrs [0 ], c .sentinelAddrs [i ] = c .sentinelAddrs [i ], c .sentinelAddrs [0 ]
886877 c .setSentinel (ctx , sentinelCli )
887878 internal .Logger .Printf (ctx , "sentinel: selected addr=%s masterAddr=%s" , addr , masterAddr )
888- shouldCancel = true
889- })
890- if shouldCancel {
891879 cancel ()
892- }
880+ })
893881 }(i , sentinelAddr )
894882 }
895883
896884 wg .Wait ()
897885 close (errCh )
898-
899886 if masterAddr != "" {
900887 return masterAddr , nil
901888 }
902889 errs := make ([]error , 0 , len (errCh ))
903890 for err := range errCh {
904891 errs = append (errs , err )
905892 }
906- if len (errs ) == 0 {
907- errs = append (errs , errors .New ("redis: no sentinels available" ))
908- }
909893 return "" , fmt .Errorf ("redis: all sentinels specified in configuration are unreachable: %s" , joinErrors (errs ))
910894}
911895
0 commit comments