What is context?
Context is a mechanism for passing specific values, cancellation signals and deadlines between goroutines in Go
context interface definition:
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{
}
Err() error
Value(key interface{
}) interface{
}
}
- The Deadline method is used to get the deadline of the Context , and returns false if no deadline is set.
- The Done method is used to obtain a read-only channel that will be closed when the Context is canceled or the deadline is reached.
- The Err method is used to get the error message of the Context, and returns nil if the Context has not been cancelled.
- The Value method is used to get the value of the specified key in the Context, and returns nil if the key does not exist.
context implementation type
There are two main types of implementations of the Context interface: cancelCtx and timerCtx
cancelCtx
type cancelCtx struct {
Context // 嵌入Context接口
mu sync.Mutex // Mutex锁,用于保证并发安全性
done chan struct{
} // 一个只读的channel,用于通知Context已经被取消
err error // Context的错误信息
}
timerCtx
type timerCtx struct {
cancelCtx // 嵌入cancelCtx结构体
deadline time.Time // 截止时间
timer *time.Timer // 定时器
}
Context creation
Created by functions such as WithCancel, WithDeadline, WithTimeout and WithValue . These functions will return a new Context and a cancel function, which can be used to cancel the operation of Context
WithCancel function
The WithCancel function is used to create a basic Context implementation, which includes a parent Context, a cancel function cancel and a read-only channel done. When using the cancel function, it will close the done channel and stop all goroutines from running
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
c := newCancelCtx(parent)
propagateCancel(parent, &c)
return &c, func() {
c.cancel(true, Canceled) }
}
WithDeadline function
The WithDeadline function and WithTimeout function are used to create a Context implementation with a deadline. When the deadline is reached, the Context is automatically canceled and the done channel is closed.
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
c := &timerCtx{
cancelCtx: newCancelCtx(parent),
deadline: deadline,
}
propagateCancel(parent, c)
d := c.deadline.Sub(time.Now())
if d <= 0 {
c.cancel(true, DeadlineExceeded)
return c, func() {
c.cancel(true, Canceled) }
}
c.timer = time.AfterFunc(d, func() {
c.cancel(true, DeadlineExceeded)
})
return c, func() {
c.cancel(true, Canceled) }
}
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
return WithDeadline(parent, time.Now().Add(timeout))
}
WithValue function
Used to create a Context implementation that contains the specified key-value pairs. These key-value pairs can pass information between multiple goroutines.
func WithValue(parent Context, key, val interface{
}) Context {
if key == nil {
panic("nil key")
}
if val == nil {
panic("nil value")
}
return &valueCtx{
parent, key, val}
}