I am making multiple RPC calls to my server where the handler looks like:
func (h *handler) GetData(ctx context.Context, request Payload) (*Data, error) {
go func(ctx context.Context) {
for {
test := 0
select {
case <-ctx.Done():
if ctx.Err() == context.Canceled {
log.Info(ctx.Err())
test = 1
break
}
}
if test == 1 {
break
}
}
}(ctx)
data := fetchData(request)
return data, nil
}
the fetchData API takes around 5 seconds to get data and reply back to my service. Meanwhile if the client requests again, then I abort the old request and fire a new request. The abort is not visible on context object.
Rather ctx.Err()
shows a value of context.Canceled
even when the calls are not cancelled and end gracefully with expected data.
I am new to Go and don't understand how exactly context manages Cancels, timeout and completion.
Some insight on the behaviour will be helpful.
From the docs (emphasize mine):
For incoming server requests, the context is canceled when the client's connection closes, the request is canceled (with HTTP/2), or when the ServeHTTP method returns.
In other words, cancellation does not necessarly mean that the client aborted the request.
Contexts that can be canceled must be canceled eventually, and the HTTP server takes care of that:
Canceling this context releases resources associated with it, so code should call cancel as soon as the operations running in this Context complete.
What you observe works as intended.