Senior · Concurrency
Cancellation is the first select case
Both ctx.Done and a timer/work channel are ready. The cancellation case appears first in source. Must it win?
Try explaining this aloud before opening the answer. State your assumptions and trace a boundary case.
package main
import (
"fmt"
"time"
)
func main() {
timer := time.NewTimer(time.Hour)
defer timer.Stop()
timer.Reset(0)
<-timer.C
fmt.Println("one owner received the reset timer")
}Reveal a strong answer
Timers have both an API contract and version-dependent implementation behavior. Modern Go timer channels avoid the old buffered stale-value behavior under the documented module/runtime conditions, but this does not let several goroutines reset, receive and decide business state without a protocol. Treat a timer as one owner’s scheduling tool and separately define which events may commit work.
For Go 1.23-and-later timer-channel semantics, inspect the module’s go directive and any asynctimerchan compatibility setting when diagnosing old patterns. Do not use len(timer.C) to synchronize. Stop/Reset documentation distinguishes modern guarantees from older drain patterns. A select with several ready cases chooses among them; listing ctx.Done first does not grant cancellation priority. One goroutine creates, resets and receives the timer. No second receiver can consume its event unexpectedly. The example does not infer fairness or a global ordering against cancellation from a timer firing. It is compatible with the modern timer contract used by the course; review the time package documentation when maintaining older modules or runtime compatibility settings.
Repeated time.After in a hot loop allocates timers and is not a substitute for a clear lifecycle. Stopping a timer does not close its channel or prove a worker exited. If cancellation must prevent a side effect, recheck the operation state under the same synchronization that commits the effect. Test ready timer plus cancellation, reset ownership and shutdown without relying on lucky sleeps.
Common trap
A lucky timer/cancellation test run does not establish a global priority or a commit ordering guarantee.
Try it
Explain select choice, timer version settings, one-owner Stop/Reset and the synchronization needed before committing a side effect.
Worked solution
Select does not grant source-order priority among ready cases. Give the timer a clear owner and check operation state at the commit boundary under the synchronization that protects the effect. Modern Timer Stop/Reset behavior differs from older compatibility modes, so inspect module go version and runtime settings when maintaining old code. Stopping a timer neither closes its channel nor joins a worker; tests need deliberate barriers and boundary cases.
Change the constraint
What can a cancellation recheck guarantee if another goroutine may commit concurrently?
How did you do?
Self-assessment, not a compiler pass or interview score. Explain the reasoning unaided before marking understood.
Not marked. Progress stays on this browser, separate from course completion.
Primary references
Checked 2026-10-28. Use documentation for your pinned runtime, driver and tool version.