golang no cancelable context

本文介绍如何在开发中避免因主协程提前退出导致的异步任务被cancel,通过PropagateContext函数创建一个nocancelable的context,保持原有的value但取消cancel机制,确保异步任务不受影响。
摘要由CSDN通过智能技术生成

在开发过程中,我们可能经常遇到需要异步处理的任务,主协程可能不会等待异步任务的完成就结束,传递给异步任务的是主协程的context,主协程退出导致context被cancel, 影响异步任务。

如果简单的给异步任务传递context.Background,可能导致一些value缺失,如trace信息。因此,需要一种no cancelable的context,能继承主协程中context的所有value,同时不继承其cancel机制,我们可以通过以下方法来实现。

// PropagateContext 繁衍一个context,取消oldCtx中的cancel机制,且继承oldCtx中的所有value。
// 对于做一些异步操作,且不希望老context中的超时或cancel机制影响操作
// 如果oldCtx中没有traceId,会随机生成一个。
func PropagateContext(oldCtx context.Context) (newCtx context.Context) {
	if oldCtx == nil {
		oldCtx = context.Background()
	}
	traceId, ok := oldCtx.Value(keyTraceID).(string)
	if traceId == "" || !ok {
		traceId = fmt.Sprintf("trace%s", util.GetRandString(27))
		oldCtx = context.WithValue(oldCtx, keyTraceID, traceId)
	}
	return contextWithoutCancel{oldCtx}
}

type contextWithoutCancel struct{ context.Context }

func (contextWithoutCancel) Deadline() (deadline time.Time, ok bool) { return }
func (contextWithoutCancel) Done() <-chan struct{}                   { return nil }
func (contextWithoutCancel) Err() error                              { return nil }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值