Skip to content

Commit 0d52843

Browse files
committed
prevention on unnecessary allocations in case of bad configuration
1 parent 00332b2 commit 0d52843

File tree

1 file changed

+19
-35
lines changed

1 file changed

+19
-35
lines changed

sentinel.go

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -806,15 +806,27 @@ func (c *sentinelFailover) RandomReplicaAddr(ctx context.Context) (string, error
806806
}
807807

808808
func (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

Comments
 (0)