context
context包
- 在goroutine中传递上下文信息、信号控制、公共参数等
context数据结构
1
2
3
4
5
6
7
type Context interface {
Deadline() (deadline time.Time, ok bool) // 获取当前context的截止时间
Done() <-chan struct{} // 识别channel是否被关闭
Err() error // 获取context被关闭的原因
Value(key interface{}) interface{} // 获取当前context中所存储的value
}
使用场景
- 子goroutine超时控制
- 上下文传递信息
context的继承
- WithCancel:创建一个可以取消的Context
- WithDeadline:创建一个到截止日期就取消的Context
- WithTimeout:创建一个超时自动取消的Context
- WithValue:在Context中设置键值对
cancelCtx 结构
1
2
3
4
5
6
7
8
type cancelCtx struct {
Context
mu sync.Mutex // protects following fields
done chan struct{} // created lazily, closed by first cancel call
children map[canceler]struct{} // set to nil by the first cancel call
err error // set to non-nil by the first cancel call
}
- mu:并发安全,加互斥锁进行操作
- done:context取消会关闭
- children:包含context对应的子集,关闭通知所有的子集context
- err:报错信息
在项目中使用
自定义mapCtx,实现了context所定义的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
type mapCtx struct { Keys map[string]interface{} } func NewContext() *mapCtx { return &mapCtx{Keys: make(map[string]interface{})} } func (*mapCtx) Deadline() (deadline time.Time, ok bool) { return } func (*mapCtx) Done() <-chan struct{} { return nil } func (*mapCtx) Err() error { return nil }
使用
1 2 3 4 5 6
func NewInfra(requestID string) *Infra { infra := new(Infra) ... infra.Context = middlecontext.NewContext() return infra }
new出的mapCtx赋值给infra
业务中就是传递infra
- 用于request_id请求链路追踪、传递权限值等
注意点
- 1、context仅通知子goroutine,子goroutine自行决定是否中断任务
- 2、context不可变,线程安全。
参考
- 煎鱼一文吃透 Go 语言解密之上下文 context:https://mp.weixin.qq.com/s/A03G3_kCvVFN3TxB-92GVw
- 深度解析go context实现原理及其源码:https://segmentfault.com/a/1190000039294140
This post is licensed under CC BY 4.0 by the author.