Skip to content

Commit f99baf4

Browse files
authored
Merge pull request #2153 from kavu/fix/2126_ringshards_panic
fix: Handle panic in ringShards Hash function when Ring got closed
2 parents 1492628 + a80b84f commit f99baf4

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

ring.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,11 @@ func (c *ringShards) Hash(key string) string {
259259
var hash string
260260

261261
c.mu.RLock()
262+
defer c.mu.RUnlock()
263+
262264
if c.numShard > 0 {
263265
hash = c.hash.Get(key)
264266
}
265-
c.mu.RUnlock()
266267

267268
return hash
268269
}
@@ -271,27 +272,22 @@ func (c *ringShards) GetByKey(key string) (*ringShard, error) {
271272
key = hashtag.Key(key)
272273

273274
c.mu.RLock()
275+
defer c.mu.RUnlock()
274276

275277
if c.closed {
276-
c.mu.RUnlock()
277278
return nil, pool.ErrClosed
278279
}
279280

280281
if c.numShard == 0 {
281-
c.mu.RUnlock()
282282
return nil, errRingShardsDown
283283
}
284284

285285
hash := c.hash.Get(key)
286286
if hash == "" {
287-
c.mu.RUnlock()
288287
return nil, errRingShardsDown
289288
}
290289

291-
shard := c.shards[hash]
292-
c.mu.RUnlock()
293-
294-
return shard, nil
290+
return c.shards[hash], nil
295291
}
296292

297293
func (c *ringShards) GetByName(shardName string) (*ringShard, error) {
@@ -300,9 +296,9 @@ func (c *ringShards) GetByName(shardName string) (*ringShard, error) {
300296
}
301297

302298
c.mu.RLock()
303-
shard := c.shards[shardName]
304-
c.mu.RUnlock()
305-
return shard, nil
299+
defer c.mu.RUnlock()
300+
301+
return c.shards[shardName], nil
306302
}
307303

308304
func (c *ringShards) Random() (*ringShard, error) {
@@ -361,9 +357,9 @@ func (c *ringShards) rebalance() {
361357

362358
func (c *ringShards) Len() int {
363359
c.mu.RLock()
364-
l := c.numShard
365-
c.mu.RUnlock()
366-
return l
360+
defer c.mu.RUnlock()
361+
362+
return c.numShard
367363
}
368364

369365
func (c *ringShards) Close() error {
@@ -381,8 +377,10 @@ func (c *ringShards) Close() error {
381377
firstErr = err
382378
}
383379
}
380+
384381
c.hash = nil
385382
c.shards = nil
383+
c.numShard = 0
386384
c.list = nil
387385

388386
return firstErr

ring_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,21 @@ var _ = Describe("Redis Ring", func() {
114114
})
115115

116116
Describe("pipeline", func() {
117+
It("doesn't panic closed ring, returns error", func() {
118+
pipe := ring.Pipeline()
119+
for i := 0; i < 3; i++ {
120+
err := pipe.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err()
121+
Expect(err).NotTo(HaveOccurred())
122+
}
123+
124+
Expect(ring.Close()).NotTo(HaveOccurred())
125+
126+
Expect(func() {
127+
_, execErr := pipe.Exec(ctx)
128+
Expect(execErr).To(HaveOccurred())
129+
}).NotTo(Panic())
130+
})
131+
117132
It("distributes keys", func() {
118133
pipe := ring.Pipeline()
119134
for i := 0; i < 100; i++ {

0 commit comments

Comments
 (0)