stackoverflower
stackoverflower

Reputation: 4063

What happens if I don't cancel a Context?

I have the following code:

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...) // Some code that creates request from payload
    ctx, cancel = context.withTimeout(ctx, time.Duration(3) * time.Second)
    defer cancel()
    return http.DefaultClient.Do(req)
}

What would happen if I didn't put defer cancel() in there? go vet warns about it:

the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak

How will the context be leaked and what impact will this have?

Upvotes: 73

Views: 32311

Answers (2)

user4436000
user4436000

Reputation: 463

If you use WithCancel, the goroutine will be held indefinitely in memory. However, if you use WithDeadline or WithTimeout without calling cancel, the goroutine will only be held until the timer expires.

This is still not best practice though, it's always best to call cancel as soon as you're done with the resource.

Upvotes: 33

Kaedys
Kaedys

Reputation: 10148

If you fail to cancel the context, the goroutine that WithCancel or WithTimeout created will be retained in memory indefinitely (until the program shuts down), causing a memory leak. If you do this a lot, your memory will balloon significantly. It's best practice to use a defer cancel() immediately after calling WithCancel() or WithTimeout()

Upvotes: 84

Related Questions