当前位置:网站首页>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/
边栏推荐
- Write a jison parser (7/10) from scratch: the iterative development process of the parser generator 'parser generator'
- MySQL foundation 02 - installing MySQL in non docker version
- Hands on deep learning (34) -- sequence model
- PHP book borrowing management system, with complete functions, supports user foreground management and background management, and supports the latest version of PHP 7 x. Database mysql
- Are there any principal guaranteed financial products in 2022?
- 华为联机对战如何提升玩家匹配成功几率
- Explanation of closures in golang
- Deadlock in channel
- 自动化的优点有哪些?
- Daughter love: frequency spectrum analysis of a piece of music
猜你喜欢

After unplugging the network cable, does the original TCP connection still exist?

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

How do microservices aggregate API documents? This wave of show~

HMS core helps baby bus show high-quality children's digital content to global developers

Opencv environment construction (I)

Regular expression (I)
![Reload CUDA and cudnn (for tensorflow and pytorch) [personal sorting summary]](/img/3f/a71b56a62d2a0d64749a6af05384f5.jpg)
Reload CUDA and cudnn (for tensorflow and pytorch) [personal sorting summary]

技术管理进阶——如何设计并跟进不同层级同学的绩效

Hands on deep learning (35) -- text preprocessing (NLP)

2022-2028 global protein confectionery industry research and trend analysis report
随机推荐
Luogu deep foundation part 1 Introduction to language Chapter 4 loop structure programming (2022.02.14)
Global and Chinese PCB function test scale analysis and development prospect planning report Ⓑ 2022 ~ 2027
Hands on deep learning (33) -- style transfer
技术管理进阶——如何设计并跟进不同层级同学的绩效
Problems encountered by scan, scanf and scanln in golang
In the case of easyUI DataGrid paging, click the small triangle icon in the header to reorder all the data in the database
Simulate EF dbcontext with MOQ - mocking EF dbcontext with MOQ
Rules for using init in golang
Global and Chinese markets for laser assisted liposuction (LAL) devices 2022-2028: Research Report on technology, participants, trends, market size and share
Deadlock in channel
How to display √ 2 on the command line terminal ̅? This is actually a blog's Unicode test article
How to batch change file extensions in win10
C # use gdi+ to add text to the picture and make the text adaptive to the rectangular area
"How to connect the network" reading notes - Web server request and response (4)
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Web端自动化测试失败原因汇总
IIS configure FTP website
浅谈Multus CNI
Reload CUDA and cudnn (for tensorflow and pytorch) [personal sorting summary]
System.currentTimeMillis() 和 System.nanoTime() 哪个更快?别用错了!