Stage 1 · Code
Packages, Modules & Concurrency Intro
Concurrency Boundaries
Use context for cancellation and timeouts, protect shared state with mutexes, and catch races with go test -race.
context.Context and Cancellation
context.Context carries cancellation signals, deadlines, and request-scoped values across API boundaries. Pass it as the first parameter to any function that does I/O or long-running work.
The cancel function returned by context.WithCancel, WithTimeout, and WithDeadline must always be called — even if the work completes normally. Not calling it leaks the context and associated resources. The standard idiom is defer cancel() immediately after the context is created.
Timeouts with context
context.WithTimeout automatically cancels after a duration. context.WithDeadline cancels at a specific time. Both are the standard way to add timeouts to HTTP requests, database calls, and any operation that can hang.
sync.Mutex for Shared State
When goroutines share mutable state, use a sync.Mutex to ensure only one goroutine accesses it at a time. The pattern is: lock before reading or writing, unlock immediately after.
The Race Detector
Go has a built-in race detector that instruments your program at runtime to detect concurrent reads and writes to the same memory. Run it with go test -race or go run -race.
# In tests (recommended — run this in CI)
go test -race ./...
# On a specific program
go run -race main.go
# Build with race detection (for production use on specific services)
go build -race -o server-race .The race detector has a small runtime overhead (5-20x slower, ~5-10x more memory). Run it in your CI test suite on every commit. Do not ship race-detected binaries to production unless you are specifically hunting a race in a controlled environment.
- Pass
context.Contextas the first parameter to every function that does I/O or long-running work. - Always
defer cancel()immediately after creating a cancellable context. - Use
sync.Mutex(orsync.RWMutex) to protect shared mutable state. - Run
go test -race ./...in CI on every commit. - Prefer channels for communicating ownership; prefer mutexes for protecting a shared cache or counter.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.