1
0
mirror of https://github.com/redis/go-redis.git synced 2025-07-28 06:42:00 +03:00

Ring Watch (#1015)

* Ring Watch
This commit is contained in:
Andrea Spacca
2019-04-22 11:48:06 +02:00
committed by Vladimir Mihailenco
parent 721116ac0e
commit be4c4f3f38
2 changed files with 297 additions and 1 deletions

35
ring.go
View File

@ -275,6 +275,7 @@ func (c *ringShards) Heartbeat(frequency time.Duration) {
func (c *ringShards) rebalance() {
hash := newConsistentHash(c.opt)
var shardsNum int
c.mu.Lock()
for name, shard := range c.shards {
if shard.IsUp() {
hash.Add(name)
@ -282,7 +283,6 @@ func (c *ringShards) rebalance() {
}
}
c.mu.Lock()
c.hash = hash
c.len = shardsNum
c.mu.Unlock()
@ -653,6 +653,39 @@ func (c *Ring) Close() error {
return c.shards.Close()
}
func (c *Ring) Watch(fn func(*Tx) error, keys ...string) error {
if len(keys) == 0 {
return fmt.Errorf("redis: Watch requires at least one key")
}
var shards []*ringShard
for _, key := range keys {
if key != "" {
shard, err := c.shards.GetByKey(hashtag.Key(key))
if err != nil {
return err
}
shards = append(shards, shard)
}
}
if len(shards) == 0 {
return fmt.Errorf("redis: Watch requires at least one shard")
}
if len(shards) > 1 {
for _, shard := range shards[1:] {
if shard.Client != shards[0].Client {
err := fmt.Errorf("redis: Watch requires all keys to be in the same shard")
return err
}
}
}
return shards[0].Client.Watch(fn, keys...)
}
func newConsistentHash(opt *RingOptions) *consistenthash.Map {
return consistenthash.New(opt.HashReplicas, consistenthash.Hash(opt.Hash))
}