当前位置:网站首页>Go context basic introduction
Go context basic introduction
2022-07-04 09:39:00 【Dynamic for a while, reconstructing the crematorium】
stay Go1.7 Introduced in context, contain goroutine Running state 、 Environmental Science 、 Information about the scene . And gradually become concurrency control 、 Standard practice of timeout control .
Why would there be context?
stay Go Of server Usually, each request will start several goroutine Work at the same time ( Some go to the database to get data , Some call the downstream interface to obtain relevant data ). And these goroutine You need to share the basic data of this request , For example, log in token、 The maximum timeout for processing requests, etc .
So we can Go server As a co process model . But there is no such model context There may be some problems . For example, during business peak , The response of downstream services is slow , The current system request has no timeout control , Then there will be more and more coordination processes waiting for downstream Services , Finally, memory usage soared , Even lead to service unavailability accidents .
For this accident , In fact, simply setting the maximum downstream processing time can be avoided . and context It is very conducive to this setting .
context Can be in a group goroutine Pass shared values in 、 Cancel message 、deadline etc. .
Local global variables
stay 《 The code of 》 It points out several disadvantages of global variables
- Inadvertent modification
- name conflict
- Strange alias
- Concurrency issues
- The initialization sequence cannot be guaranteed
- Hindering code reuse
- It interferes with modularity
Personally, I think the most serious problem of global variables should be coupling . Others are relatively easy to say
But global variables also have the advantage of improving the scope of data .
So many languages design variables that are not so global . such as Java Medium ThreadLocal, Global within the thread , Avoid thread conflicts . Another example Go Medium context
about context Directly reflect this point is WithValue, And for WithTimeout、WithCancel In fact, it is also a global control variable
Basic use
There are mainly two ways to create context
- context.Backgroud(): Context default , All other contexts derive from him . Usually used for main function 、 initialization 、 Test or top-level context
- context.TODO(): When you are not sure which context to use
Both are actually type emptyCtx int
In practice, we still need to pass the following four With Method to derive
// WithCancel Return a copy of the parent process , And there is a new Done channel. When returned cancel Function called or parent context Done When the channel is closed , Returns the context of Done The passage will be closed , Whichever occurs first .
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
// WithDeadline Returns a copy of the parent context , The deadline is adjusted to be no later than d. If the deadline of the parent context is earlier than d, WithDeadline(parent, d) Semantically equivalent to parent.
// When the deadline expires 、 Call returned cancel Function or parent context Done When the channel is closed , Returns the context of Done The passage will be closed , Whichever comes first .
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
return WithDeadline(parent, time.Now().Add(timeout))
}
// WithValue Return a copy of the parent element , Where the value associated with the key is val.
// Context values are only used to pass processes and api Data within the scope of the request , Instead of passing optional parameters to functions .
// The keys provided must be comparable , Should not be string Type or any other built-in type , To avoid using context Conflicts between packages . Use WithValue Users of should define their own key types . In the interface {} assignment , To avoid distribution , Context keys usually have specific types struct{}. in addition , The static type of the exported context key variable should be a pointer or interface .
func WithValue(parent Context, key, val interface{
}) Context
Transfer shared data
Often used for some “ Global variables ”. For example, the following code sends the request reqID, Because after that, the code basically needs to use , So you can use context
Personal opinions are actually unnecessary context Transfer shared data . If the code is functionally cohesive, it can be abstracted into structure , Use shared data as a structure . If there are not many transmission links , You can also send parameters directly . If it is “ overall situation ” Shared variables , That can also be done through chan Or other ways to share , Of course context It is also one of other methods .
func TestContextPassValue(t *testing.T) {
handler := withRequestID(http.HandlerFunc(handle))
http.ListenAndServe("/", handler)
}
const reqKey = 0
func withRequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// fetch request id from header
rid := req.Header.Get("X-Request-ID")
ctx := context.WithValue(req.Context(), reqKey, rid)
req = req.WithContext(ctx)
next.ServeHTTP(rw, req)
})
}
func handle(rw http.ResponseWriter, req *http.Request) {
reqID := req.Context().Value(reqKey)
...
}
Cancel goroutine
Someone once said context The real solution is to cancel . The three uses mentioned in this article , There are often other and even better ways to transfer shared data ; prevent goroutine Let the cat out of the , In fact, it is also a kind of cancellation goroutine To achieve . But cancel the function of downstream Services , only context It can be solved in the simplest way .
prevent goroutine Let the cat out of the
Suppose we are working on a chat software , It has real-time scanning of user folders to protect “ Security ” The function of .
func imApp() {
close:=make(chan struct{
})
go scanFiles()
select {
case <-close:
return
}
}
func scanFiles() {
// scan user file
}
At this time, the user informs us that app close , Then maybe app Other functions are turned off , But scanning files goroutine It's been running .
At this time, in order to prevent this kind of situation , have access to context To prevent this infinite operation goroutine Let the cat out of the .
func imApp() {
close := make(chan struct{
})
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go scanFiles(ctx)
select {
case <-close:
return
}
}
func scanFiles(ctx context.Context) {
select {
case <-ctx.Done():
return
default:
// scan user file partly
}
}
This can be cancelled at most , I scanned it again .
Use with caution context
context Although very good , Perfect for writing server, Especially for cancellation . But if it is abused everywhere , It may spread like a virus . also context It is actually a linked list implementation , The efficiency is relatively low .
Ref
- https://zhuanlan.zhihu.com/p/68792989
- https://www.cnblogs.com/qcrao-2018/p/11007503.html
- https://www.zhihu.com/question/269905592/answer/364438511
- https://faiface.github.io/post/context-should-go-away-go2/
边栏推荐
- Rules for using init in golang
- Global and Chinese market of sampler 2022-2028: Research Report on technology, participants, trends, market size and share
- 《网络是怎么样连接的》读书笔记 - 集线器、路由器和路由器(三)
- Log cannot be recorded after log4net is deployed to the server
- Les différents modèles imbriqués de listview et Pageview avec les conseils de flutter
- Sort out the power node, Mr. Wang he's SSM integration steps
- 2022-2028 global protein confectionery industry research and trend analysis report
- 《网络是怎么样连接的》读书笔记 - 认识网络基础概念(一)
- The child container margin top acts on the parent container
- xxl-job惊艳的设计,怎能叫人不爱
猜你喜欢

2022-2028 global protein confectionery industry research and trend analysis report

2022-2028 global optical transparency industry research and trend analysis report

Svg image quoted from CodeChina

百度研发三面惨遭滑铁卢:面试官一套组合拳让我当场懵逼

华为联机对战如何提升玩家匹配成功几率

MySQL foundation 02 - installing MySQL in non docker version

C # use gdi+ to add text with center rotation (arbitrary angle)

Kubernetes CNI 插件之Fabric

Regular expression (I)

libmysqlclient.so.20: cannot open shared object file: No such file or directory
随机推荐
Report on investment analysis and prospect trend prediction of China's MOCVD industry Ⓤ 2022 ~ 2028
2022-2028 global small batch batch batch furnace industry research and trend analysis report
Leetcode (Sword finger offer) - 35 Replication of complex linked list
If you can quickly generate a dictionary from two lists
Daughter love: frequency spectrum analysis of a piece of music
Global and Chinese markets for laser assisted liposuction (LAL) devices 2022-2028: Research Report on technology, participants, trends, market size and share
JDBC and MySQL database
pcl::fromROSMsg报警告Failed to find match for field ‘intensity‘.
Dynamic analysis and development prospect prediction report of high purity manganese dioxide in the world and China Ⓡ 2022 ~ 2027
How to display √ 2 on the command line terminal ̅? This is actually a blog's Unicode test article
Fatal error in golang: concurrent map writes
el-table单选并隐藏全选框
"How to connect the network" reading notes - Web server request and response (4)
Go context 基本介绍
Global and Chinese market of bipolar generators 2022-2028: Research Report on technology, participants, trends, market size and share
2022-2028 global industry research and trend analysis report on anterior segment and fundus OTC detectors
Global and Chinese markets of thrombography hemostasis analyzer (TEG) 2022-2028: Research Report on technology, participants, trends, market size and share
Explanation of closures in golang
What is uid? What is auth? What is a verifier?
lolcat