写点什么

Golong Context package

作者:陈庆宗
  • 2022-12-04
    广东
  • 本文字数:2430 字

    阅读完需:约 8 分钟

概述

Package context 定义了Context类型,它带有dealines, cancellation信号,以及跨边界 API 与进程间的请求范围值。


对服务器的传入请求应该创建一个 context,对服务器的传出调用应该接受一个 context。函数链之间的调用也必须传递 Context,可选择用一个衍生的 context 代替,衍生的 context 可使用WithCancel,WithDealine, WithTImeout, 或WithValue创建。当一个 Context 被取消时,从它那里衍生的所有 Context 也应该全部被取消。


使用 Contexts 的程序应该遵循这些规则,以保持接口在包之间的一致性,并启用静态分析工具来检查 context 传播:

  • 不要将 context 存储在结构类型中;相反,将 Context 显式传递给需要它的每个函数。 Context 应该是第一个参数,通常命名为 ctx:

func DoSomething(ctx context.Context, arg Arg) error {	// ... use ctx ...}
复制代码
  • 不要传递 nil Context,即使函数允许。如果您不确定要使用哪个上下文,请传递 context.TODO。

  • 仅将 Context 的值用于传输进程和 API 的请求范围的数据,而不是将可选参数传递给函数。

  • 相同的 Context 可能会传递给运行在不同 goroutine 中的函数;多个 goroutine 同时使用上下文是安全的。

Functions

func WithCancel

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
复制代码

WithCancel 返回带有新 Done 通道的 parent 的副本。当返回的取消函数被调用或父上下文的 Done 通道关闭时,返回的上下文的 Done 通道被关闭,以先发生者为准。

取消此 context 释放与其关联的资源,因此代码应在此 context 中运行的操作完成后立即调用取消。


func WithDeadline

func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
复制代码

WithDeadline 返回父上下文的副本,截止日期调整为不晚于 d。 如果父级的截止日期已经早于 d,则 WithDeadline(parent, d) 在语义上等同于父级。 当截止日期到期、调用返回的取消函数或父 context 的 Done 通道关闭时,返回的上下文的 Done 通道将关闭,以先发生者为准。


func WithTImeout

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
复制代码

WithTimeout返回WithDeadline(parent, time.Now().Add(timeout))


type CancelFunc

type CancelFunc func()
复制代码

CancelFunc 告诉一个操作放弃它的工作。CancelFunc 不会等待其他工作而停止。一个 CancelFunc 可能被多个 goroutines 同时被调用。第一个调用完成后,随后的调用 CancelFunc 将不会做任何事


type Context

type Context interface {		// Deadling 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.  	// the close of the Done channel may happen asynchronously,  	// after the cancel function returns.  	//  	// 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{}  	  	// If Done is not yet closed, Err returns nil.  	// If Done is close, Err return a non-nil error explaining why:  	// Caceled if the context was canceled  	// or DeadlineExceeded if the context's deadline passed.  	// After Err returns a non-nil error, successive calls to Err return the   	// same error.  	Err() error	  	  	// Value returns the value associated with this context for key, or nil  	// if no value is associated with key. Successive call to Value with  	// the same key return the same result.  	//  	// Use context values only for request-scoped data that transits  	// processed and API boundaries, not for passing optional parameters to  	// functions.  	//  	// A key identifies a specific value in a context. Funcions that wish  	// to store values in Context typically allocate a key in a global  	// variable then use that key as the argument to context.WithValue and  	// Context.Value. A key can be any type that supports equality.  	// packages should define keys as an unexported type to avoid collisions  	Value(key any) any	}
复制代码


上下文携带截止日期、取消信号和其他跨 API 边界的值


func Background

func Background() Context
复制代码

Background 返回一个 non-nil,空 Context。它永远不会被取消,没有 values,也没有截止日期。它通常由 main 函数、初始化和测试使用,并作为传入请求的顶级上下文。


func TODO

func TODO() Context
复制代码

TODO 返回一个 non-nil,空 Context。当不清楚要使用哪个 Context 或它尚不可用时(因为尚未扩展周围函数以接受 Context 参数),代码应使用 context.TODO


func WithValue

func WithValue(parent Context, key, val any) Context
复制代码

WithValue 返回一个 parent 的副本,副本值关联的键值是 val


仅将 Context 的值用于传输进程和 API 的请求范围的数据,而不是将可选参数传递给函数。


提供的 key 必须是可比较的,并且不应是字符串类型或任何其他内置类型,以避免使用上下文的包之间发生冲突。WithValue 的用户应该为键定义他们自己的类型。为了避免在分配给 interface{} 时进行分配,上下文 key 通常具有具体类型 struct{}。或者,导出的上下文 key 变量的静态类型应该是指针或接口。


Reference

https://pkg.go.dev/context@go1.19.3

用户头像

陈庆宗

关注

还未添加个人签名 2021-05-11 加入

还未添加个人简介

评论

发布
暂无评论
Golong Context package_Context_陈庆宗_InfoQ写作社区