Skip to content

Archive

Cancellation

4 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.

Software Engineering 15 Sep 2026 8 min read

Task Scopes Bind Child Lifetimes to Parent Operations

An asynchronous function can return while work it started is still running. Once that happens, the caller no longer has a lexical boundary that states when the spawned work finishes, where its failure is observed, or which operation owns its cancellation. Structured concurrency changes that lifetime relation. Child tasks belong to an enclosing scope, and the scope does not complete until its children reach a terminal state according to the runtime’s task-group semantics. The central property is not parallel execution. It is that task lifetime follows program structure.

Software Engineering 13 Sep 2026 9 min read

Cancellation Is a Protocol, Not a Thread Kill

A caller can stop waiting for a result while the operation producing that result continues to run. The distinction is easy to miss because many APIs expose cancellation through a single method, token, context, or signal. That surface can look like a command to terminate work. In most cooperative designs, it is closer to a state transition: further work is no longer wanted. The gap matters once an operation owns resources, crosses process boundaries, or has already produced side effects. A cancelled HTTP request does not retroactively erase a committed database transaction. A task that notices a cancellation token between two writes cannot make the first write disappear. A parent that abandons a child computation also needs a rule for who observes the child’s eventual completion and who releases anything the child owns.