mirror of
https://github.com/redis/go-redis.git
synced 2025-06-11 03:21:38 +03:00
perf: avoid unnecessary copy operation (#3376)
* optime: reduce unnecessary copy operations * add a comment * trigger CI without code changes, because the bug of docker * add comments
This commit is contained in:
21
ring.go
21
ring.go
@ -349,17 +349,16 @@ func (c *ringSharding) newRingShards(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warning: External exposure of `c.shards.list` may cause data races.
|
||||||
|
// So keep internal or implement deep copy if exposed.
|
||||||
func (c *ringSharding) List() []*ringShard {
|
func (c *ringSharding) List() []*ringShard {
|
||||||
var list []*ringShard
|
|
||||||
|
|
||||||
c.mu.RLock()
|
c.mu.RLock()
|
||||||
if !c.closed {
|
defer c.mu.RUnlock()
|
||||||
list = make([]*ringShard, len(c.shards.list))
|
|
||||||
copy(list, c.shards.list)
|
|
||||||
}
|
|
||||||
c.mu.RUnlock()
|
|
||||||
|
|
||||||
return list
|
if c.closed {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return c.shards.list
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ringSharding) Hash(key string) string {
|
func (c *ringSharding) Hash(key string) string {
|
||||||
@ -423,6 +422,7 @@ func (c *ringSharding) Heartbeat(ctx context.Context, frequency time.Duration) {
|
|||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
var rebalance bool
|
var rebalance bool
|
||||||
|
|
||||||
|
// note: `c.List()` return a shadow copy of `[]*ringShard`.
|
||||||
for _, shard := range c.List() {
|
for _, shard := range c.List() {
|
||||||
err := shard.Client.Ping(ctx).Err()
|
err := shard.Client.Ping(ctx).Err()
|
||||||
isUp := err == nil || err == pool.ErrPoolTimeout
|
isUp := err == nil || err == pool.ErrPoolTimeout
|
||||||
@ -582,6 +582,7 @@ func (c *Ring) retryBackoff(attempt int) time.Duration {
|
|||||||
|
|
||||||
// PoolStats returns accumulated connection pool stats.
|
// PoolStats returns accumulated connection pool stats.
|
||||||
func (c *Ring) PoolStats() *PoolStats {
|
func (c *Ring) PoolStats() *PoolStats {
|
||||||
|
// note: `c.List()` return a shadow copy of `[]*ringShard`.
|
||||||
shards := c.sharding.List()
|
shards := c.sharding.List()
|
||||||
var acc PoolStats
|
var acc PoolStats
|
||||||
for _, shard := range shards {
|
for _, shard := range shards {
|
||||||
@ -651,6 +652,7 @@ func (c *Ring) ForEachShard(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
fn func(ctx context.Context, client *Client) error,
|
fn func(ctx context.Context, client *Client) error,
|
||||||
) error {
|
) error {
|
||||||
|
// note: `c.List()` return a shadow copy of `[]*ringShard`.
|
||||||
shards := c.sharding.List()
|
shards := c.sharding.List()
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
errCh := make(chan error, 1)
|
errCh := make(chan error, 1)
|
||||||
@ -682,6 +684,7 @@ func (c *Ring) ForEachShard(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Ring) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, error) {
|
func (c *Ring) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, error) {
|
||||||
|
// note: `c.List()` return a shadow copy of `[]*ringShard`.
|
||||||
shards := c.sharding.List()
|
shards := c.sharding.List()
|
||||||
var firstErr error
|
var firstErr error
|
||||||
for _, shard := range shards {
|
for _, shard := range shards {
|
||||||
@ -810,7 +813,7 @@ func (c *Ring) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) er
|
|||||||
|
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
if key != "" {
|
if key != "" {
|
||||||
shard, err := c.sharding.GetByKey(hashtag.Key(key))
|
shard, err := c.sharding.GetByKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user