在使用场景中可以看到context包本身包含了数个导出函数,包括WithValue、WithTimeout等,无论是最初构造context还是传导context,最核心的接口类型都是context.Context,任何一种context也都实现了该接口,包括value context。 到底有几种context? 既然context都需要实现Context,那么包括不直接可见(非导出)的结构体,一共有几种c...
func WithValue(parent Context, key, val interface{}) Context {} withValue 会构造一个新的context,新的context 会包含一对 Key-Value 数据,可以通过Context.Value(Key) 获取存在 ctx 中的 Value 值。 通过上面的理解可以直到,Context 是一个树状结构,一个 Context 可以派生出多个不一样的Context。我们大概可以...
context包提供了4个方法创建不同类型的context,使用这四个方法时如果没有父context,都需要传入backgroud,即backgroud作为其父节点: WithCancel() WithDeadline() WithTimeout() WithValue() context包中实现Context接口的struct,除了emptyCtx外,还有cancelCtx、timerCtx和valueCtx三种,正是基于这三种context实例,实现了上述...
=nil{c.mu.Unlock()return// already canceled}c.err=errifc.done==nil{c.done=closedchan}else{close(c.done)}forchild:=range c.children{// NOTE: acquiring the child's lock while holding parent's lock.// 子*cancelCtx不用执行removeChild()操作,自底向上递归清理了children.child.cancel(false,err...
mu.Lock() defer c.mu.Unlock() if c.err == nil { c.timer = time.AfterFunc(dur, func() { c.cancel(true, DeadlineExceeded) }) } return c, func() { c.cancel(true, Canceled) } } WithDeadline 函数,返回父上下文的一个副本,其截止日期调整为不迟于d。如果父上下文的截止日期已经早于...
cancelCtx.Context, c) } c.mu.Lock() if c.timer != nil { c.timer.Stop() c.timer = nil } c.mu.Unlock() } timerCtx是基于cancelCtx的,此外多了timer和deadline,timer指最长存活时间,比如将在多少秒后结束,deadline表示最后期限,需要指定具体的截止日期,由此衍生出了WithDeadline()和WithTimeout(...
context实际上只定义了接口,凡是实现该接口的类都可称为是一种context,官方包中实现了几个常用的context,分别可用于不同的场景。 2.1 接口定义 源码包中src/context/context.go:Context定义了该接口: type Contextinterface{ Deadline() (deadline time.Time, okbool) ...
context 包定义了Context接口类型,它可以具有生命周期、取消/关闭的channel信号、请求域范围的健值存储功能。 因此可以用它来管理goroutine 的生命周期、或者与一个请求关联,在functions之间传递等。 每个Context应该视为只读的,通过WithCancel、WithDeadline、WithTimeout和WithValue函数可以基于现有的一个Context(称为父Cont...
func (c *timerCtx) cancel(removeFromParent bool, err, cause error) { c.cancelCtx.cancel(false, err, cause) if removeFromParent { // Remove this timerCtx from its parent cancelCtx's children. removeChild(c.cancelCtx.Context, c) } c.mu.Lock if c.timer != nil { c.timer.Stop c.timer...
() r, ok := nameResolver[schema+serviceName] rwNameResolverMutex.RUnlock() if ok { return r.grpcClientConn } rwNameResolverMutex.Lock() r, ok = nameResolver[schema+serviceName] if ok { rwNameResolverMutex.Unlock() return r.grpcClientConn } r, err := NewResolver(schema, etcdaddr, ...