net/context's WithDeadline()
and WithTimeout()
functions both return a cancel
function, which docs say to always call with a defer, such as:
func slowOperationWithTimeout(ctx context.Context) (Result, error) {
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel() // releases resources if slowOperation completes before timeout elapses
But what "resources" are actually being released in this function?
The code example you give comes from the context.WithTimeout
documentation, here it is again slightly modified:
func slowOperationWithTimeout(parentContxt context.Context) (Result, error) {
childContext, cancel := context.WithTimeout(parentContxt, 100*time.Millisecond)
defer cancel() // releases resources if slowOperation completes before timeout elapses
return slowOperation(childContext)
}
(Here I've renamed ctx
to make it clear which I'm talking about, in real code it's better to just use ctx
as you don't want or need to distinguish the parent/child contextes.)
Calling the returned cancel function does (at least) two important things. First, it closes the channel that childContext.Done()
returns. This might be import if, for example, slowOperation
started something in a goroutine with that context (or a [grand]child context).
Second, cancelling childContext
tells parentContext
to forget about it. There are references to the child context in the local variable and another in the parent's list of all it's children (and any references slowOperation
may have kept). If it's not cancelled when it's no longer needed, the parent wastes space keeping it around until the child context eventually times out and cancels itself, among other things that can delay the child context and it's done channel from being garbage collected.
It's also possible a context implementation (or a future change) could have other resources used until cancelled. If the documentation says you should do something, then do it (even if it were to do nothing in current implementations). In that sense, the answer to "Why?" for such things is simply, "Because the documentation said that's the correct way to use it".