16

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.

Ashwin Shirva
  • 1,331
  • 1
  • 12
  • 31
Em Ae
  • 8,167
  • 27
  • 95
  • 162
  • 1
    "context cancelled means that the given request has timed out, correct?" Nope. Timeouts produce [context.DeadlineExceeded](https://golang.org/pkg/context/#pkg-variables). Cancelled means one of the CancelFuncs has been called, nothing more nothing less. – Peter Jun 15 '20 at 08:20

1 Answers1

20

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)

Ashwin Shirva
  • 1,331
  • 1
  • 12
  • 31