Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait of function result after context cancellation

Tags:

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?

like image 987
goofinator Avatar asked Dec 18 '19 08:12

goofinator


People also ask

What causes context canceled?

That context is canceled if the HTTP client disconnects or cancels the HTTP request (possible in HTTP/2). Passing an HTTP request's context to QueryWithTimeout above would cause the database query to stop early either if the overall HTTP request was canceled or if the query took more than five seconds.

Is context thread safe Golang?

It is thread safe: You can't modify the value of a context key once it has been set. The only way set another value for a given key is to create another context variable using context.

What is context background () in Golang?

Background returns a non-nil, empty Context. It is never canceled, has no values, and has no deadline. It is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests.


1 Answers

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.

like image 195
chmike Avatar answered Sep 27 '22 20:09

chmike