Timers in consumer.go and memqueue/queue.go are not cleaned up properly on Stop() and Reset() calls.
Per the Go docs:
- https://pkg.go.dev/time#Timer.Stop
To ensure the channel is empty after a call to Stop, check the return value and drain the channel. For example, assuming the program has not received from t.C already
- https://pkg.go.dev/time#Timer.Reset
For a Timer created with NewTimer, Reset should be invoked only on stopped or expired timers with drained channels.
If a program has already received a value from t.C, the timer is known to have expired and the channel drained, so t.Reset can be used directly. If a program has not yet received a value from t.C, however, the timer must be stopped and—if Stop reports that the timer expired before being stopped—the channel explicitly drained
Both recommend this pattern:
if !timer.Stop() {
<-timer.C
}
Unfortunately, the <-t.C channel read can block if the channel has already been read. As such, this pattern will prevent the read from blocking:
if !timer.Stop() {
select {
case <-timer.C:
default:
}
}
Timers in
consumer.goandmemqueue/queue.goare not cleaned up properly onStop()andReset()calls.Per the Go docs:
Both recommend this pattern:
Unfortunately, the
<-t.Cchannel read can block if the channel has already been read. As such, this pattern will prevent the read from blocking: