Skip to content

Timers are not cleaned up properly on Stop and Reset #156

@shaunco

Description

@shaunco

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:
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions