golang context包源码梳理与解析

108 阅读2分钟

context包是go语言中非常重要的一个包 用于管理上下文 在kubernetes中也是应用非常广 同时整个包代码只有560行左右 非常适合阅读 本文做一个整体结构的梳理

interface

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}
type canceler interface {
    cancel(removeFromParent bool, err error)
    Done() <chan struct{}
}
type stringer interface {
    String() string
}

这三个接口是整个包的核心 后续的struct结构体 func函数都是为了实现/继承这些接口而准备的

struct

type deadlineExceededError struct{}

实现了三个method
func (deadlineExceededError) Error() string   { return "context deadline exceeded" }
func (deadlineExceededError) Timeout() bool   { return true }
func (deadlineExceededError) Temporary() bool { return true }
type cancelCtx struct {
    Context //Context接口 
    mu sync.Mutex
    done chan struct{}
    children map[canceler]struct{} //此处canceler是interface中的接口
    err error
}

实现了5个method
func (c *cancelCtx) Value(key interface{}) interface{} {} //实现了Context接口
func (c *cancelCtx) Done() <-chan struct{} {} //实现了Context和canceler接口
func (c *cancelCtx) Err() error {} //实现了Context接口
func (c *cancelCtx) String() string {} //实现了stringer接口
func (c *cancelCtx) cancel(removeFromParent bool, err error) {} //实现了canceler接口
type timerCtx struct {
   cancelCtx //结构体嵌套
   timer *time.Timer // Under cancelCtx.mu.
   deadline time.Time
}

实现了3个method
func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {} //实现了Context接口
func (c *timerCtx) String() string {} //实现了stringer接口
func (c *timerCtx) cancel(removeFromParent bool, err error) {} //实现了canceler接口 同时内部实现调用了cancelCtx里的cancel方法
type valueCtx struct {
   Context
   key, val interface{}
}

实现了2个method
func (c *valueCtx) Value(key interface{}) interface{} {} //实现了Context接口
func (c *valueCtx) String() string {} //实现了stringer接口

这几个结构体将接口实现 并调用单独的func 是整个包实现的细节

func

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, d time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key interface{}, val interface{}) Context

这四个函数是我们import的时候调用的 也是对外提供的 比如

 ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) 
 defer cancel()  

具体的实现留待各位去研究 这里只是给出梳理 方便阅读的时候更加快速

最后给出一张整理的图

image.png