Golang Context
date
Nov 27, 2020
slug
golang-context
status
Published
tags
Golang
summary
Context In Golang
type
Post
Context In Golang
Overview
the context in golang has some functions and types.
We can see them in document
context package functions:
2 types:
important type -- context
So we can sure there are three roles of context:
- Carry deadlines
- Cancellation signals
- Save Request-scoped values
When we use it?
In the actual situation, we will meet some questions:
- how to cancel a goroutine
- how to cancel a RPC/HTTP request
- how to trace a RPC/HTTP request
- ...
Due to a RPC/HTTP request is goroutine in Golang, so we can use context to cancel the request by canceling goroutine.
Context can be put in a binary tree, actually, it has parent and child node.
So when we want to cancel a request cross many goroutine, we can use context tree.
Every node in the tree will sub the chan
Done
, when a node received the signal, the children will invoke cancel()
.And type context has a map struct, so we can save k-v data in it.
But it is better to save immutable information like:
- request id
- trace id
- user auth token
Create a context
First we can create a empty context by
Background()
and TODO()
.There are same function.
But using
TODO()
that means you don't know which context to use ot it is not yet available.A empty context is never canceled, has no values, and has no deadline.
We usually use them in following:
- main function
- initialization
- test case
- top-level Context for incoming requests
When we have a context, we can use
WithCancel()
, WithDeadline()
and WithTimeout()
to create a child one.We can see the source of
WithCancel()
:The
propagateCancel
will connect parent and child of cancel function.First, if a context is empty, can be created by
Background()
, Done()
, or is never canceled, can be created by WithValue(emptyCtx, key, value)
, the propagateCancel
will do nothing, parent will have no effect on children.And then, the function will use
select
to sub parent chan Done
, if parent is done, child will cancel immediately.If not, the child will put into parent's a list of children.
If developer custom the type of context, the function will run a goroutine to sub chan
child.Done
and parent.Done
.Pass Value
Sometimes, we want to trace a request in RPC/HTTP. We can put a trace id in headers or meta data.
In goroutine, we can pass some immutable information in context.
And we should control the key, and use
GetXXX()
and WithXXX()
to get and set value.Using
There are currently two ways to integrate Context objects into your API:
- The first parameter of a function call
- Optional config on a request structure
A great mental model of using Context is that it should flow through your program. Imagine a river or running water. This generally means that you don’t want to store it somewhere like in a struct. Nor do you want to keep it around any more than strictly needed. Context should be an interface that is passed from function to function down your call stack, augmented as needed. Ideally, a Context object is created with each request and expires when the request is over.
Different with Gin Context
Gin use context to extend middleware.
The framework is as like
koa
in Node.js.The middleware will be invoked twice in request and response.
And if we want to pass value in middleware, we can put k-v data in context.
But also, context of gin had implement the golang context interface.