@@ -310,11 +310,10 @@ func (c *ringShards) Random() (*ringShard, error) {
310310}
311311
312312// Heartbeat monitors state of each shard in the ring.
313- func (c * ringShards ) Heartbeat (frequency time. Duration , closeCh chan struct {} ) {
313+ func (c * ringShards ) Heartbeat (ctx context. Context , frequency time. Duration ) {
314314 ticker := time .NewTicker (frequency )
315315 defer ticker .Stop ()
316316
317- ctx := context .Background ()
318317 for {
319318 select {
320319 case <- ticker .C :
@@ -332,7 +331,7 @@ func (c *ringShards) Heartbeat(frequency time.Duration, closeCh chan struct{}) {
332331 if rebalance {
333332 c .rebalance ()
334333 }
335- case <- closeCh :
334+ case <- ctx . Done () :
336335 return
337336 }
338337 }
@@ -392,10 +391,10 @@ func (c *ringShards) Close() error {
392391//------------------------------------------------------------------------------
393392
394393type ring struct {
395- opt * RingOptions
396- shards * ringShards
397- cmdsInfoCache * cmdsInfoCache //nolint:structcheck
398- hearbeatCloseSignal chan struct {}
394+ opt * RingOptions
395+ shards * ringShards
396+ cmdsInfoCache * cmdsInfoCache //nolint:structcheck
397+ heartbeatCancelFn context. CancelFunc
399398}
400399
401400// Ring is a Redis client that uses consistent hashing to distribute
@@ -421,20 +420,20 @@ type Ring struct {
421420func NewRing (opt * RingOptions ) * Ring {
422421 opt .init ()
423422
424- hearbeatCloseSignal := make ( chan struct {} )
423+ hbCtx , hbCancel := context . WithCancel ( context . Background () )
425424
426425 ring := Ring {
427426 ring : & ring {
428- opt : opt ,
429- shards : newRingShards (opt ),
430- hearbeatCloseSignal : hearbeatCloseSignal ,
427+ opt : opt ,
428+ shards : newRingShards (opt ),
429+ heartbeatCancelFn : hbCancel ,
431430 },
432431 }
433432
434433 ring .cmdsInfoCache = newCmdsInfoCache (ring .cmdsInfo )
435434 ring .cmdable = ring .Process
436435
437- go ring .shards .Heartbeat (opt .HeartbeatFrequency , hearbeatCloseSignal )
436+ go ring .shards .Heartbeat (hbCtx , opt .HeartbeatFrequency )
438437
439438 return & ring
440439}
@@ -722,6 +721,7 @@ func (c *Ring) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) er
722721// It is rare to Close a Ring, as the Ring is meant to be long-lived
723722// and shared between many goroutines.
724723func (c * Ring ) Close () error {
725- close (c .hearbeatCloseSignal )
724+ c .heartbeatCancelFn ()
725+
726726 return c .shards .Close ()
727727}
0 commit comments