What's the difference between time.Ticker and repeated time.After? What happens if the consumer is slow?
Question 200MediumGo 1.22 to 1.25
A Ticker delivers ticks on a fixed schedule through one reusable channel. If the receiver falls behind, the ticker drops ticks instead of queuing them (the channel holds at most one pending tick), so it adjusts to slow receivers. Repeated time.After measures the interval from each loop iteration, so the period drifts by however long the processing takes.
tk := time.NewTicker(time.Second)
defer tk.Stop() // pre-1.23: required to free it; still good hygiene
for {
select {
case <-ctx.Done():
return
case t := <-tk.C:
doWork(t) // if doWork takes 3s, ticks in between are dropped
}
}
Gotchas: time.Tick (the function) returns only a channel with no way to stop it. Before Go 1.23 it leaked forever. It's GC-safe now, but still can't be stopped. NewTicker panics on a non-positive duration. Use tk.Reset(d) to change the period.
More on Channels & select
- Q198How do you implement a timeout on a channel operation? Compare
time.After,time.NewTimer, andcontext. - Q199Does
time.Afterin a loop leak memory? How did Go 1.23 change this? - Q201How do you do a non-blocking send or receive?
- Q202What does this print? (select evaluation order)
- Q203How would you implement a semaphore / bounded concurrency with channels?
- Q204Implement a worker pool with result collection and proper shutdown.