go context专题(二)- context设计目的和基本数据结构
设计目的
context库的设计目的就是跟踪 goroutine调用树,并在在这些gouroutine调用树中传递通知和元数据。两个目的:
1.退出通知机制 (主要目的)
2.传递元数据 (辅助功能)
基本的数据结构
为了理解context的实现,需要理解下设计规则:context的创建者称为root节点,其一般是一个处理上下文的独立goroutine。root节点负责创建Context的具体对象,并将其传递到其下游调用的goroutine. 下游的goroutine可以继续封装改Context对象(使用装饰者模式)再传递更下游的goroutine.这些下游goroutine的Context 对象实例都要逐层向上注册。这样通过root节点的Context对象就可以遍历整个Context对象树,所以通知也能通知到下游的goroutine.
1. 2个接口
Context接口
是一个基本的接口,所有的Context对象都要实现该接口,context的使用者在在调用接口中都是使用Context最为参数类型。
具体解释如下
#Context接口
type Context interface {
//如果Context实现了超时控制,该方法返回ok true deadline为超时时间,否则ok 为false
Deadline() (deadline time.Time, ok bool)
//后端被调的goroutine应该监听该方法返回的chan,以便及时的释放资源
Done() <-chan struct{}
//Done返回的chan收到通知的时候,才可以访问Err()获知因为什么原因被取消
Err() error
//可以访问上游goroutine传递给下游goroutine的值
Value(key interface{}) interface{}
}
canceler接口
是一个扩展接口,其规定了取消通知的Context 具体类型需要实现的接口。context包中:*cancelCtx and *timerCtx 都实现了该接口。
// A canceler is a context type that can be canceled directly. The
// implementations are *cancelCtx and *timerCtx.
//一个Context 对象如果实现了canceler接口,可以被取消
type canceler interface {
//cancel 是主调goroutine负责调用
cancel(removeFromParent bool, err error)
//Done方法返回的chan需要后端goroutine来监听,并及时退出
Done() <-chan struct{}
}
2. empty Context结构
emptyCtx 实现了Context接口,但是不具备任何功能,因为其所有的方法都是空实现。其存在的目的是为Context的对象提供一个root根。
因为context的使用思路就是不停的调用context包提供的包装函数创建具有特殊功能的Context实例,使用emptyCtx的实例最为第一层包装。
#emptyCtx实现了Context接口
type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return
}
func (*emptyCtx) Done() <-chan struct{} {
return nil
}
func (*emptyCtx) Err() error {
return nil