I am new to Go
and still learning it every signle day. I see a lot of context cancelled
error in our project which is kind of annoying me. So i was thinking to dig a little deeper to figure out whats going on.
If I am not wrong, in "simple" terms, context cancelled means that the given request (via grpc using gokit) has been time out. Correct? If so what should be best way to fix this issue?
Should I look into why these requests are being timed out (probably underlying db queries are taking long or something) and fix those?
Is it something Go
internal which may be hinting about something related to Go
?
What will be the best approach to start handling this error? Right now, all I see "Context cancelled" and have no idea why so.
In some cases you can see “proxy error: context canceled” error message in the Gateway logs. The error itself means that the connection was closed unexpectedly. It can happen for various reasons, and in some cases it is totally fine: for example client can have unstable mobile internet.
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.
Listening For Cancellation The Context type provides a Done() method. This returns a channel that receives an empty struct{} type every time the context receives a cancellation event. So, to listen for a cancellation event, we need to wait on <- ctx. Done() .
A context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
Incoming requests to a server should create a Context, and outgoing calls to servers should accept a Context.
A context cancelled error doesnot necessarily mean a time out error.
If you are using go routines, if the parent go routine finishes but child routine still runs in the background, and the child go routine had a context which is common to the parent go routine this can end up in a context cancelled, if the parent go routine closes context before exiting.
So if the child routine does not have dependency on parent routine context, it is always a good practice to create a new context for background go routines. A new context can be created using the context.Background()
If your application is microservice based(or have several components which call each other using contexts), if microservice 1 calling microservice 2, and microservice 2 eplicitly closes or cancels context, even in that case you can get this error.
A context can be closed by calling the cancel()
function as shown below:
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
Cancelling this context releases resources associated with it. So if the callee has explicitly closed the context as shown above, this can result in a context cancelled error at caller.
These context cancelled errors can be handled checking the context.Canceled
error from a grpc.Dial()
call(if you are using grpc)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With