time.After(duration) returns a channel that receives a time value after the duration elapses. Use it in select statements for deadlines or inactivity warnings; use time.Sleep when the goal is only to pause execution. section 10.2
func consumer(ch <-chan Event) {
for {
select {
case event := <-ch: #1
handle(event)
case <-time.After(time.Hour): #2
log.Println("warning: no messages received")
}
}
}
This consumer waits for either a message or one hour of silence. Because time.After is evaluated on every iteration, each received message resets the timeout. section 10.2
The loop can nevertheless accumulate memory. Each call creates timer resources and a channel that remain allocated until the timeout expires; receiving a message does not release them. In Go 1.15, one call used about 200 bytes, so five million calls per hour could retain roughly 1 GB. The returned receive-only channel cannot be closed programmatically. section 10.2
Choose the replacement according to the loop’s lifetime and timer requirements:
- Use context.WithTimeout when cancellation should be explicit, calling cancel after receiving a message. Recreating the context on every iteration is itself not lightweight. section 10.2
- Use a reusable time.Timer when the loop repeatedly needs the same timeout; create it once and reset it for subsequent iterations. section 10.2
- Keep time.After for cases where the timer lifetime and allocation pattern are not repeated heavily, rather than applying it blindly inside loops or handlers. section 10.8
package time
func After(d Duration) <-chan Time {
return NewTimer(d).C #1
}
The implementation shows why time.After creates timer resources: it returns the channel produced by time.NewTimer. section 10.2
func consumer(ch <-chan Event) {
timerDuration := 1 * time.Hour
timer := time.NewTimer(timerDuration) #1
for { #2
timer.Reset(timerDuration) #3
select {
case event := <-ch:
handle(event)
case <-timer.C: #4
log.Println("warning: no messages received")
}
}
}
A reusable timer avoids constructing a new time.After timer during every loop iteration. section 10.2
