goofinator
goofinator

Reputation: 67

Wait of function result after context cancellation

I can't understand the logic of this example in Go Concurrency Patterns: Context

func httpDo(ctx context.Context, req *http.Request, f func(*http.Response, error) error) error {
    // Run the HTTP request in a goroutine and pass the response to f.
    c := make(chan error, 1)
    req = req.WithContext(ctx)
    go func() { c <- f(http.DefaultClient.Do(req)) }()
    select {
    case <-ctx.Done():
        <-c // Wait for f to return.
        return ctx.Err()
    case err := <-c:
        return err
    }
}

Before that it is said that:

The Done method returns a channel that acts as a cancellation signal to functions running on behalf of the Context: when the channel is closed, the functions should abandon their work and return.

It looks like the equivalent of awaiting of <-c only, without case <-ctx.Done() at all. So, what is the point?

Upvotes: 5

Views: 2096

Answers (2)

chmike
chmike

Reputation: 22174

The context may cancel the Do call. The case <-ctx.Done() unambiguously identify that this happened.

Indeed, we may assume that the Do call would then return a nil http.Response, and that the function f would then return an error when this happens. But we wouldn’t know why f received a nil http.Response as input argument.

The instruction case err := <-c: handles the case when the error is produced inside f.

Upvotes: 3

Lars Christian Jensen
Lars Christian Jensen

Reputation: 1642

It is not equivalent to awaiting <-c only. The example returns a different value (ctx.Err()) when the context is closed.

Upvotes: 1

Related Questions