> On 9 Jan 2021, at 9:50 am, Amit Saha <amitsaha...@gmail.com> wrote:
> 
> Say I have created a RequestWithContext:
> 
> r, err := http.NewRequestWithContext(ctx, "GET", 
> "http://127.0.0.1:8080/healthcheck";, nil)
> 
> Now, I make the request in the context of *another* HTTP request handling 
> function:
> 
> Func myHandler(w http.ResponseWriter, r *http.Request) {
> ...
> 
> resp, err := client.Do(r)
> if err != nil {
>       http.Error(w, err.Error(), http.StatusInternalServerError)
> }
>      return
> }
> …
> }
> 
> 
> When I cancel this context, the above http.Error() call triggers a 
> superfluous write header message.
> I dug down a bit and I can see that when the context is cancelled, the 
> finishRequest() function 
> (https://golang.org/src/net/http/server.go?h=finishRequest#L1613) is called 
> which essentially writes a 200 status code. Hence, when the code above goes 
> to write an error, it gets the superfluous writeHeader message.
> 
> I then updated my code above to be:
> 
> resp, err := client.Do(r)
> if err != nil {
>       if err != context.Canceled {
>               http.Error(w, err.Error(), http.StatusInternalServerError)
>       }
>     return
> }
> 
> Wondering if anyone has any thoughts on this pattern and if there is any 
> reason why we complete the full lifecycle of finsihRequest() on context 
> cancellation even if it is going to fail somewhere down the line since in 
> this case, the client has already disconnected?

I missed the complete handler function which will make the query more sensible:

func getData(ctx context.Context, w http.ResponseWriter) {
        done := make(chan bool)
        client := http.Client{}

        go func() {
                r, err := http.NewRequestWithContext(ctx, "GET", 
"http://127.0.0.1:8080/healthcheck";, nil)
                if err != nil {
                        http.Error(w, err.Error(), 
http.StatusInternalServerError)
                        return
                }
                resp, err := client.Do(r)
                if err != nil && err != context.Canceled {
                                http.Error(w, err.Error(), 
http.StatusInternalServerError)
                        }
                        return
                }
                defer resp.Body.Close()
                io.Copy(w, resp.Body)
                done <- true
        }()

        select {
        case <-done:
                return

        case <-ctx.Done():
                log.Printf("api: client disconnected.")
                return # This return triggers the finishRequest() function call 
to be made
        }
}




-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/73125598-E476-41BC-9A37-B20958448372%40gmail.com.

Reply via email to