Skip to content

Archive

Context

9 articles
Go 16 Sep 2026 3 min read

Go context.AfterFunc Stop Does Not Wait for Callback Completion

The stop function returned by Go’s context.AfterFunc does not wait for a callback that has already started. A false result therefore marks a state boundary, not a completion barrier: the callback may be running concurrently when stop returns. context.AfterFunc(ctx, f) associates f with cancellation of ctx. Cancellation starts f in its own goroutine. If the context is already canceled at registration time, the callback is started promptly in a new goroutine rather than being invoked synchronously by the caller.

Go 16 Sep 2026 4 min read

Go Context Cancellation Cause Follows the First Cancellation

A Go context records its cancellation cause when cancellation first reaches that context. Later cancellation attempts do not replace the recorded cause. This makes context.Cause a record of the winning cancellation event rather than a mutable error slot. The distinction matters in context trees because parent and child cancellation can race. The first event to cancel a given node fixes that node’s cause, while another node in the same tree can retain a different cause.

Go 12 Sep 2026 5 min read

Run Cancellation Callbacks with context.AfterFunc in Go

context.AfterFunc attaches a callback to context cancellation without adding a goroutine that waits only on ctx.Done(). When the context becomes done, the callback starts in its own goroutine. The small API hides a concurrency boundary that matters when the callback mutates shared state, interrupts blocking I/O, or competes with normal completion. The function arrived in Go 1.21 and returns a stop function. That return value is not a general cancellation handle for the callback. It controls the association between the context and the callback, with precise behavior once cancellation and callback startup begin to race.

Go 12 Sep 2026 5 min read

Preserve Cancellation Causes in Go Contexts

A canceled Go context normally reports one of two broad states through ctx.Err(): context.Canceled or context.DeadlineExceeded. That is enough to stop work, but it can discard the event that triggered cancellation. A worker failure, shutdown request, quota rejection, and explicit abort can all collapse into the same context.Canceled value. Go provides cause-aware context functions for cases where the cancellation signal and the diagnostic error need to travel together. context.WithCancelCause creates a derived context whose cancel function accepts an error, while context.Cause retrieves the recorded cause.

Go 12 Sep 2026 4 min read

Detach Go Context Cancellation with context.WithoutCancel

A Go context usually ties a unit of work to the lifetime of its parent. Cancel an HTTP request context, and derived contexts observe that cancellation. This propagation is the normal contract, but some follow-up operations need a different lifetime while still carrying request-scoped values. Go 1.21 added context.WithoutCancel for that boundary. It returns a context that can resolve values through its parent but does not inherit the parent’s cancellation state or deadline.

Go 08 Sep 2026 7 min read

Run Cleanup After Context Cancellation with context.AfterFunc

Cancellation often means more than telling a goroutine to stop. A blocked operation may need to be interrupted, a temporary resource may need cleanup, or some state may need to be released as soon as a request deadline expires. A common approach is to start another goroutine that waits on ctx.Done(). That works, but it adds lifecycle code every time you need cancellation-triggered behavior. Since Go 1.21, the standard context package provides context.AfterFunc for this job.

Go 08 Sep 2026 7 min read

Detach Go Work Safely with context.WithoutCancel

Request cancellation is usually exactly what a Go service wants. When a client disconnects or a request deadline expires, database calls, HTTP requests, and other downstream work should normally stop too. Sometimes one small piece of work has a different lifetime. A handler may need to enqueue an audit record, finish a bounded cache update, or send a best-effort notification after the request itself is no longer alive. Passing the request context directly makes that work inherit cancellation. Replacing it with context.Background() avoids cancellation, but also throws away useful request-scoped values.

Go 01 Sep 2026 2 min read

Preserve Cancellation Causes with context.WithCancelCause in Go

Go’s context.Context propagates deadlines and cancellation across API boundaries. Traditional cancellation tells downstream work that it should stop, but ctx.Err() only reports context.Canceled or context.DeadlineExceeded. Sometimes the reason matters. Go 1.20 introduced context.WithCancelCause, and later releases added cause-aware deadline helpers. They preserve a domain error without changing normal cancellation behavior. Attach a cause to cancellation package main import ( "context" "errors" "fmt" ) var ErrSuperseded = errors.New("request superseded") func main() { ctx, cancel := context.WithCancelCause(context.Background()) cancel(ErrSuperseded) fmt.Println(ctx.Err()) // context canceled fmt.Println(context.Cause(ctx)) // request superseded } Code that only understands Context still sees ordinary cancellation. Code that needs diagnostic detail can call context.Cause.

Go 01 Sep 2026 7 min read

Graceful HTTP Server Shutdown in Go

Stopping a web server with Ctrl+C looks harmless during development, but production deployments need a more careful shutdown process. If a process exits immediately, active HTTP requests can be interrupted, clients may receive connection errors, and in-flight work can be left unfinished. Go’s standard library already provides the pieces needed for a clean shutdown. The main tools are os/signal, context, and http.Server.Shutdown. This guide shows a practical pattern for shutting down an HTTP server when the process receives SIGINT or SIGTERM.