A deadline marks a point in time after which ongoing work should stop or be treated as expired. It may be expressed as a duration from now or as a specific time. In Go, a context carries that deadline to operations such as I/O requests and channel waits. section 8.6.1 section 8.6
A common mistake is performing channel sends or receives as unconditional blocking operations. If the deadline expires while they wait, the function cannot respond promptly. Select on both the channel operation and ctx.Done(), then return ctx.Err(). section 8.6.4
type publisher interface {
Publish(ctx context.Context, position flight.Position) error
}
Accept a context at the API boundary so the caller can communicate a deadline or cancellation signal. section 8.6.1
Publishing the latest radar position
A publisher has four seconds to publish a flight position because consumers only want the latest position. Create the context with context.WithTimeout, defer cancel(), and pass the derived context to Publish. The deferred cancellation releases the context's internal goroutine when the surrounding function returns. section 8.6.1
type publishHandler struct {
pub publisher
}
func (h publishHandler) publishPosition(position flight.Position) error {
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) #1
defer cancel() #2
return h.pub.Publish(ctx, position) #3
}
The complete timeout-based publishing shape combines a four-second deadline, deferred cleanup, and context propagation. section 8.6.1
func f(ctx context.Context) error {
// ...
select { #1
case <-ctx.Done():
return ctx.Err()
case ch1 <- struct{}{}:
}
select { #2
case <-ctx.Done():
return ctx.Err()
case v := <-ch2:
// ...
}
}
Use select around every potentially blocking channel send or receive so expiration interrupts the operation instead of leaving it waiting. section 8.6.4


