Golang编程之context命令使用

Package context

import "context"

context包定义了Context上下文类型,它跨API边界和进程之间承载截止日期、取消信号和其他请求范围的值。

对于服务器的传入请求应该创建一个Context上下文,而对服务器的传出调用也应该接受该Context上下文。它们之间的函数调用链必须传播Context上下文,可以选择将其替换为使用WithCancelWithDeadlineWithTimeoutWithValue创建的派生Context上下文。当一个Context上下文被取消时,从它派生的所有Context上下文也被取消。

WithCancelWithDeadlineWithTimeout函数接受一个Context上下文(父级)并返回派生Context上下文(子级)和CancelFunc。调用CancelFunc将取消子级及其子级,删除父级对子级的引用,并停止任何关联的计时器。如果不调用CancelFunc,则会泄漏子级及其子级,直到父级被取消或计时器触发。Go-Vet工具检查取消功能是否用于所有控制流路径。

使用Context上下文的程序应该遵循这些规则,以保持包之间的接口一致,并允许静态分析工具检查上下文传播:

不要将上下文存储在结构类型中;而是将Context上下文显式传递给每个需要它的函数。并且Context上下文应该是第一个参数,通常名为ctx:

func DoSomething(ctx context.Context, arg Arg) error {
	// ... use ctx ...
}

即使函数允许,也不要传递nil上下文。如果不确定要使用哪个Context上下文,请传递context.TODO。

只对传输进程和API的请求范围数据使用Context上下文值,而不用于向函数传递可选参数。

同一Context上下文可以传递给在不同goroutine中运行的函数;上下文对于多个goroutine同时使用是安全的。

请参阅https://blog.golang.org/context,以获取使用上下文的服务器的示例代码。

Index

Variables
type CancelFunc
type Context
func Background

Variables

var Canceled = errors.New("context canceled")

当Context上下文被取消时,Canceled会返回Context.Err错误。

var DeadlineExceeded error = deadlineExceededError{}

当Context上下文的截止时间过去时,DeadLineExceeded会返回Context.Err错误。

type CancelFunc

type CancelFunc func()

CancelFunc会发起一个操作放弃其工作。CancelFunc不会等待工作停止。在第一次调用之后,对CancelFunc的后续调用不做任何操作。

type Context

type Context interface {
    // Deadline返回代表此上下文完成工作的时间
    // 应该取消。如果没有截止日期,截止日期返回ok==false
    // 设置。对截止日期的连续调用返回相同的结果。
    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 is provided for use in select statements:
    //
    //  // Stream generates values with DoSomething and sends them to out
    //  // until DoSomething returns an error or ctx.Done is closed.
    //  func Stream(ctx context.Context, out chan<- Value) error {
    //  	for {
    //  		v, err := DoSomething(ctx)
    //  		if err != nil {
    //  			return err
    //  		}
    //  		select {
    //  		case <-ctx.Done():
    //  			return ctx.Err()
    //  		case out <- v:
    //  		}
    //  	}
    //  }
    //
    // See https://blog.golang.org/pipelines for more examples of how to use
    // a Done channel for cancelation.
    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.
    //
    // Use context values only for request-scoped data that transits
    // processes and API boundaries, not for passing optional parameters to
    // functions.
    //
    // A key identifies a specific value in a Context. Functions 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.
    //
    // Packages that define a Context key should provide type-safe accessors
    // for the values stored using that key:
    //
    // 	// Package user defines a User type that's stored in Contexts.
    // 	package user
    //
    // 	import "context"
    //
    // 	// User is the type of value stored in the Contexts.
    // 	type User struct {...}
    //
    // 	// key is an unexported type for keys defined in this package.
    // 	// This prevents collisions with keys defined in other packages.
    // 	type key int
    //
    // 	// userKey is the key for user.User values in Contexts. It is
    // 	// unexported; clients use user.NewContext and user.FromContext
    // 	// instead of using this key directly.
    // 	var userKey key = 0
    //
    // 	// NewContext returns a new Context that carries value u.
    // 	func NewContext(ctx context.Context, u *User) context.Context {
    // 		return context.WithValue(ctx, userKey, u)
    // 	}
    //
    // 	// FromContext returns the User value stored in ctx, if any.
    // 	func FromContext(ctx context.Context) (*User, bool) {
    // 		u, ok := ctx.Value(userKey).(*User)
    // 		return u, ok
    // 	}
    Value(key interface{}) interface{}
}

一个Context上下文跨越API边界携带一个截止日期、一个取消信号和其他值。

Context上下文的方法可以由多个goroutine同时调用。

func Background

func Background() Context

Background返回非零的空上下文。它从不被取消,没有值,也没有最后期限。它通常由主函数、初始化和测试使用,并且作为传入请求的顶级上下文。

func TODO

func TODO() Context

TODO返回非零的空上下文。当不清楚要使用哪个上下文或者它还不可用时(因为周围的函数还没有被扩展以接受上下文参数),代码应该使用 context.TODO。静态分析工具可以识别TODO,它确定上下文是否在程序中正确传播。

func WithCancel

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)

WithCancel返回具有新完成通道的父级副本。当调用返回的cancel函数或关闭父上下文的Done通道时(以先发生者为准),将关闭返回的上下文的Done通道。

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

func WithDeadline

func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)

WithDeadline返回父上下文的副本,其截止时间调整为不迟于d。如果父上下文的截止时间早于d,则WithDeadline(Parent,d)在语义上等同于父上下文。当截止时间到期、调用返回的cancel函数或关闭父上下文的done通道(以先发生者为准)时,返回的上下文的done通道将关闭。

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

func WithTimeout

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

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

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

func slowOperationWithTimeout(ctx context.Context) (Result, error) {
	ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
	defer cancel()  // releases resources if slowOperation completes before timeout elapses
	return slowOperation(ctx)
}

func WithValue

func WithValue(parent Context, key, val interface{}) Context

WithValue返回父级的副本,其中与键关联的值为val。

只对传输进程和API的请求范围数据使用上下文值,而不用于向函数传递可选参数。

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

转载于:https://my.oschina.net/u/4198654/blog/3099233

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值