Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Context Cancelled errors

Tags:

go

grpc

grpc-go

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?

  1. Should I look into why these requests are being timed out (probably underlying db queries are taking long or something) and fix those?

  2. Is it something Go internal which may be hinting about something related to Go?

  3. What will be the best approach to start handling this error? Right now, all I see "Context cancelled" and have no idea why so.

like image 388
Em Ae Avatar asked Jun 15 '20 03:06

Em Ae


People also ask

What is context Cancelled error?

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.

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.

What happens when a context is Cancelled Golang?

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() .


1 Answers

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.

Scenario 1:

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()

Scenario 2:

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)

like image 78
Ashwin Shirva Avatar answered Sep 18 '22 22:09

Ashwin Shirva