Context【Golang】
来自智得网
(重定向自Context(Golang))
简介
对于分布式系统的交互,除了调用时明确的参数传递之外,传入一些上下文信息是一个良好的工程实践,上下文中可以传入本次调用的一些环境信息,例如发起的IP地址,发起的请求等。
因为分布式系统调用的拓扑关系一般是一个有向无环图,所以上下文也同样存在层级关系或者父子关系,下游的上下文带有上游上下文传入的所有信息,还可以加入自己的信息。
由于存在父子关系,所以上下文除了信息传递之外还可以进行一些控制信息的传递,例如传递超时,取消信息,一旦一个节点的上下文触发了取消,取消信息可以传播给其所有的子孙节点。
Golang的context就是上述上下文的一种实现,Golang的协程之间存在各种较为复杂的关系,比如一个通道的关闭可能会触发多个协程的关闭,还有微服务场景下更为复杂的级联关系,比如http执行过程会可能会启用一个新的协程发起rpc调用,如何优雅的管理这些协程的退出,例如在请求已经超时的情况,把整个调用链的协程全部关闭,Context就可以承担这个功能。
原理
context是golang中定义的一个接口
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
context包中提供了context接口的一些实现类,例如emptyCtx,valueCtx,cancelCtx,timerCtx等。
emptyCtx
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
}
func (*emptyCtx) Value(key interface{}) interface{} {
return nil
}
func (e *emptyCtx) String() string {
switch e {
case background:
return "context.Background"
case todo:
return "context.TODO"
}
return "unknown empty Context"
}
var (
background = new(emptyCtx)
todo = new(emptyCtx)
)
func Background() Context {
return background
}
func TODO() Context {
return todo
}