4

I'm using time.Ticker to do some stuff at a regular interval. I want to be able to change the frequency that stuff happens at:

for {
        select {
        case <-ticker.C:
            //do stuff
        case t := <-newTicker:
            oldTicker := ticker
            ticker = t
            oldTicker.Stop()
        }
    }

Do I need that ticker cleanup to avoid a memory leak, or will reassigning ticker like

case ticker := <-newTicker:

be enough?

theeddieh
  • 519
  • 1
  • 3
  • 8

2 Answers2

3

As JimB mentioned as per time package GoDoc.

Under time.NewTicker, the following is mentioned.

Stop the ticker to release associated resources.

Provided you run oldTimer.Stop(), oldTicker will get garbage collected after exiting the case statement as it's out of scope.

John S Perayil
  • 6,001
  • 1
  • 32
  • 47
  • In this case, trying to close the channel gives the following error: `cannot close receive-only channel`. [This question](https://stackoverflow.com/questions/8593645/is-it-ok-to-leave-a-channel-open) indicates that it is not necessary to close every channel, that the garbage collector wil pick up that `oldTicker.C` can be cleaned up. My concern is that if this runs for a while there will be many `oldTicker`s left around. – theeddieh Nov 15 '16 at 09:34
  • Sorry about that. The answer you linked to is right. 'timer.C' is a receive only channel `<-chan Time`. The last part of the answer is wrong. – John S Perayil Nov 15 '16 at 10:28
1

Instead of using a chan time.Ticker use a chan time.Duration and send a time.Duration to be used by the ticker's Reset() method.

for {
        select {
        case <-ticker.C:
            //do stuff
        case t := <-newTickerDuration: // (chan time.Duration)
            ticker.Reset(t)     
        }
    }

Send the new duration instead of a new ticker and call the ticker's Reset() method passing in the time.Duration that was received on the channel. This will stop and reset the ticker with the new duration without the need to create a new ticker each time. The accepted answer does answer the question, but it would result in increased garbage collection and waste resources.