Skip to content

Commit 18b2e30

Browse files
committed
Cleanup cmds info
1 parent d5f5c24 commit 18b2e30

File tree

3 files changed

+67
-33
lines changed

3 files changed

+67
-33
lines changed

cluster.go

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -300,17 +300,21 @@ func (c *clusterNodes) GC(generation uint32) {
300300
}
301301
}
302302

303-
func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
303+
func (c *clusterNodes) Get(addr string) (*clusterNode, error) {
304304
var node *clusterNode
305305
var err error
306-
307306
c.mu.RLock()
308307
if c.closed {
309308
err = pool.ErrClosed
310309
} else {
311310
node = c.allNodes[addr]
312311
}
313312
c.mu.RUnlock()
313+
return node, err
314+
}
315+
316+
func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
317+
node, err := c.Get(addr)
314318
if err != nil {
315319
return nil, err
316320
}
@@ -580,11 +584,11 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
580584
opt.init()
581585

582586
c := &ClusterClient{
583-
opt: opt,
584-
nodes: newClusterNodes(opt),
585-
cmdsInfoCache: newCmdsInfoCache(),
587+
opt: opt,
588+
nodes: newClusterNodes(opt),
586589
}
587590
c.state = newClusterStateHolder(c.loadState)
591+
c.cmdsInfoCache = newCmdsInfoCache(c.cmdsInfo)
588592

589593
c.process = c.defaultProcess
590594
c.processPipeline = c.defaultProcessPipeline
@@ -630,17 +634,39 @@ func (c *ClusterClient) retryBackoff(attempt int) time.Duration {
630634
return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff)
631635
}
632636

633-
func (c *ClusterClient) cmdInfo(name string) *CommandInfo {
634-
cmdsInfo, err := c.cmdsInfoCache.Do(func() (map[string]*CommandInfo, error) {
635-
node, err := c.nodes.Random()
637+
func (c *ClusterClient) cmdsInfo() (map[string]*CommandInfo, error) {
638+
addrs, err := c.nodes.Addrs()
639+
if err != nil {
640+
return nil, err
641+
}
642+
643+
var firstErr error
644+
for _, addr := range addrs {
645+
node, err := c.nodes.Get(addr)
636646
if err != nil {
637647
return nil, err
638648
}
639-
return node.Client.Command().Result()
640-
})
649+
if node == nil {
650+
continue
651+
}
652+
653+
info, err := node.Client.Command().Result()
654+
if err == nil {
655+
return info, nil
656+
}
657+
if firstErr == nil {
658+
firstErr = err
659+
}
660+
}
661+
return nil, firstErr
662+
}
663+
664+
func (c *ClusterClient) cmdInfo(name string) *CommandInfo {
665+
cmdsInfo, err := c.cmdsInfoCache.Get()
641666
if err != nil {
642667
return nil
643668
}
669+
644670
info := cmdsInfo[name]
645671
if info == nil {
646672
internal.Logf("info for cmd=%s not found", name)
@@ -704,13 +730,14 @@ func (c *ClusterClient) slotMasterNode(slot int) (*clusterNode, error) {
704730

705731
func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error {
706732
if len(keys) == 0 {
707-
return fmt.Errorf("redis: keys don't hash to the same slot")
733+
return fmt.Errorf("redis: Watch requires at least one key")
708734
}
709735

710736
slot := hashtag.Slot(keys[0])
711737
for _, key := range keys[1:] {
712738
if hashtag.Slot(key) != slot {
713-
return fmt.Errorf("redis: Watch requires all keys to be in the same slot")
739+
err := fmt.Errorf("redis: Watch requires all keys to be in the same slot")
740+
return err
714741
}
715742
}
716743

command.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,17 +1027,21 @@ func (cmd *CommandsInfoCmd) readReply(cn *pool.Conn) error {
10271027
//------------------------------------------------------------------------------
10281028

10291029
type cmdsInfoCache struct {
1030+
fn func() (map[string]*CommandInfo, error)
1031+
10301032
once internal.Once
10311033
cmds map[string]*CommandInfo
10321034
}
10331035

1034-
func newCmdsInfoCache() *cmdsInfoCache {
1035-
return &cmdsInfoCache{}
1036+
func newCmdsInfoCache(fn func() (map[string]*CommandInfo, error)) *cmdsInfoCache {
1037+
return &cmdsInfoCache{
1038+
fn: fn,
1039+
}
10361040
}
10371041

1038-
func (c *cmdsInfoCache) Do(fn func() (map[string]*CommandInfo, error)) (map[string]*CommandInfo, error) {
1042+
func (c *cmdsInfoCache) Get() (map[string]*CommandInfo, error) {
10391043
err := c.once.Do(func() error {
1040-
cmds, err := fn()
1044+
cmds, err := c.fn()
10411045
if err != nil {
10421046
return err
10431047
}

ring.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,11 @@ func NewRing(opt *RingOptions) *Ring {
304304
opt.init()
305305

306306
ring := &Ring{
307-
opt: opt,
308-
shards: newRingShards(),
309-
cmdsInfoCache: newCmdsInfoCache(),
307+
opt: opt,
308+
shards: newRingShards(),
310309
}
310+
ring.cmdsInfoCache = newCmdsInfoCache(ring.cmdsInfo)
311+
311312
ring.processPipeline = ring.defaultProcessPipeline
312313
ring.cmdable.setProcessor(ring.Process)
313314

@@ -428,21 +429,23 @@ func (c *Ring) ForEachShard(fn func(client *Client) error) error {
428429
}
429430
}
430431

431-
func (c *Ring) cmdInfo(name string) *CommandInfo {
432-
cmdsInfo, err := c.cmdsInfoCache.Do(func() (map[string]*CommandInfo, error) {
433-
shards := c.shards.List()
434-
firstErr := errRingShardsDown
435-
for _, shard := range shards {
436-
cmdsInfo, err := shard.Client.Command().Result()
437-
if err == nil {
438-
return cmdsInfo, nil
439-
}
440-
if firstErr == nil {
441-
firstErr = err
442-
}
432+
func (c *Ring) cmdsInfo() (map[string]*CommandInfo, error) {
433+
shards := c.shards.List()
434+
firstErr := errRingShardsDown
435+
for _, shard := range shards {
436+
cmdsInfo, err := shard.Client.Command().Result()
437+
if err == nil {
438+
return cmdsInfo, nil
443439
}
444-
return nil, firstErr
445-
})
440+
if firstErr == nil {
441+
firstErr = err
442+
}
443+
}
444+
return nil, firstErr
445+
}
446+
447+
func (c *Ring) cmdInfo(name string) *CommandInfo {
448+
cmdsInfo, err := c.cmdsInfoCache.Get()
446449
if err != nil {
447450
return nil
448451
}

0 commit comments

Comments
 (0)