最初接触golang http源码的时候就发现有一个比较特别的package context,当时顺便把它的源码给看了下,了解下它的工作原理,并且在后面学习etcd源码的时候发现几乎每一个回调相关的函数都会有一个ctx参数。今天终于闲下来了,对于context这么常用的package还是做下笔记为好。
context包在golang源码的golang.org/x/net/context目录下,context主要用在结束若干个相互具有父子(主任务子任务)关系的goroutine,context内部本身就是以一种树形递归的形式去组织各个context节点,父节点的取消,会递归的把取消信号发送给它的子节点。
Context接口的定义如下:
type Context interface {
// Deadline returns the time when work done on behalf of this context
// should be canceled. Deadline returns ok==false when no deadline is
// set. Successive calls to Deadline return the same results.
Deadline() (deadline time.Time, ok bool)
// Done returns a channel that's closed when work done on behalf of this
// context should be canceled. Done may return nil if this context can
// never be canceled. Successive calls to Done return the same value.
//
// WithCancel arranges for Done to be closed when cancel is called;
// WithDeadline arranges for Done to be closed when the deadline
// expires; WithTimeout arranges for Done to be closed when the timeout
// elapses.
Done() <-chan struct{}
// Err returns a non-nil error value after Done is closed. Err returns
// Canceled if the context was canceled or DeadlineExceeded if the
// context's deadline passed. No other values for Err are defined.
// After Done is closed, successive calls to Err return the same value.
Err() error
// Value returns the value associated with this context for key, or nil
// if no value is associated with key. Successive calls to Value with
// the same key returns the same result.
Value(key interface{}) interface{}
}
Deadline:主要用于设定超时时间的Context上,它的返回值用于表示该Context取消的时间点。
Done:函数主要是返回一个单向的接收channel,在Context被取消之后该接收channel会返回一个值或者被关闭,都会执行select中对应的语句,这些语句一般是结束当前函数执行,并做一些清理工作。
Err:返回该Conext被取消的原因。
Value:返回该Context中key关联的值。
由于Context是基于父子类关系的属性结构组织的,无论我们是自己定义的Context还是使用golib提供的Context类,我们都会基于一个父Context,实际开发中我们使用的这个父Context大多数情况下是Background函数返回的Context:
// Background returns a non-nil, empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
// requests.
func Background() Context {