返回顶部
首页 > 资讯 > 后端开发 > GO >golang如何去除context的deadline
  • 565
分享到

golang如何去除context的deadline

go去除contextdeadlinegocontextdeadline 2023-03-21 11:03:29 565人浏览 安东尼
摘要

目录golang 去除 context 的 deadline背景方法一,创建一个新 context方法二,使用自定义结构体Golang 去除 context 的 deadline 背

Golang 去除 context 的 deadline

背景

在使用 context 的时候遇到了开协程处理任务的情况,但是直接在协程里使用主线程的 context 会导致当主线程返回时协程任务也会因为 context cancel 而失败。
本文提供了两种办法可以取消掉 context 里的 timeout 和 deadline,再设置一个新的 timeout 上去。

方法一,创建一个新 context

最简单的方案是通过创建一个新的 context 来解决这个问题。

func main() {
	ctx := context.WithValue(context.Background(), "trace", "123")
	ctx, cancel := context.WithTimeout(ctx, time.Second)
	defer cancel()

	go func(ctx context.Context) {
		newCtx := context.WithValue(context.Background(), "trace", ctx.Value("trace"))
		// do something with newCtx
	}(ctx)

	fmt.Println("main finished")
}

但是这种方案有一个缺点,当生成一个新的 context 的时候,需要手动把老 context 中的 value 手动拿出来,再设置到新的里面去。 但是在很多情况下,这个 context 是上游传过来的,并不知道 value 里面有哪些具体的 key。或者里面的 value 过多,写起来很麻烦。

方法二,使用自定义结构体

通过看 context 的源码,其实可以发现 context 是一个 interface,这就给了我们操作的空间。

type Context interface {
	Deadline() (deadline time.Time, ok bool)
	Done() <-chan struct{}
	Err() error
	Value(key any) any
}

Context 是通过 Deadline() 这个函数控制整个 ctx 是否超时了的。那么我们就可以通过重写这个函数来规避超时。

// contextWithoutDeadline 伪造了一个没有 deadline 的 context
type contextWithoutDeadline struct {
	ctx context.Context
}

func (*contextWithoutDeadline) Deadline() (time.Time, bool) {
	return time.Time{}, false
}

func (*contextWithoutDeadline) Done() <-chan struct{} {
	return nil
}

func (*contextWithoutDeadline) Err() error {
	return nil
}

func (l *contextWithoutDeadline) Value(key interface{}) interface{} {
	return l.ctx.Value(key)
}

// DetachDeadline 从 context 剥离 deadline
func DetachDeadline(ctx context.Context) context.Context {
	return &contextWithoutDeadline{ctx: ctx}
}

// SetNewTimeout 设置新的超时时间
func SetNewTimeout(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
	return context.WithTimeout(DetachDeadline(ctx), timeout)
}

可以通过 DetachDeadline() 方法来将原 ctx 的 deadline 取消掉,或者直接通过 SetNewTimeout 的方法设置一个新的超时时间上去。

演示

func main() {
	ctx, _ := context.WithTimeout(context.Background(), time.Duration(10)*time.Second)
	fmt.Println(ctx.Deadline())

	newCtx := contextwarp.DetachDeadline(ctx)
	fmt.Println(newCtx.Deadline())

	newCtx2, _ := contextwarp.SetNewTimeout(ctx, time.Duration(1)*time.Second)
	fmt.Println(newCtx2.Deadline())
}

符合预期。

到此这篇关于golang如何去除 context 的 deadline的文章就介绍到这了,更多相关go去除 context 的 deadline内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: golang如何去除context的deadline

本文链接: https://lsjlt.com/news/200686.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • golang如何去除context的deadline
    目录golang 去除 context 的 deadline背景方法一,创建一个新 context方法二,使用自定义结构体golang 去除 context 的 deadline 背...
    99+
    2023-03-21
    go去除 context deadline go context deadline
  • golang怎么去除context的deadline
    今天小编给大家分享一下golang怎么去除context的deadline的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。go...
    99+
    2023-07-05
  • GoLang context包如何使用
    本文小编为大家详细介绍“GoLang context包如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“GoLang context包如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧...
    99+
    2023-07-05
  • vue如何去除#
    这篇文章主要为大家展示了“vue如何去除#”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue如何去除#”这篇文章吧。1、vue项目,在浏览器中看到的路由都是带...
    99+
    2024-04-02
  • 如何去除php中的deprecated
    本篇内容介绍了“如何去除php中的deprecated”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php去除deprecated的方法:1...
    99+
    2023-06-25
  • jquery如何去除br
    本文小编为大家详细介绍“jquery如何去除br”,内容详细,步骤清晰,细节处理妥当,希望这篇“jquery如何去除br”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。 ...
    99+
    2024-04-02
  • thinkphp如何去除bom
    这篇“thinkphp如何去除bom”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“thinkphp如何去除bom”文章吧。t...
    99+
    2023-07-04
  • golang如何去除多余空白字符(含制表符)
    看代码吧~ //利用正则表达式压缩字符串,去除空格或制表符 func compressStr(str string) string { if str == "" { ...
    99+
    2024-04-02
  • php如何去除utf8的符号
    本文小编为大家详细介绍“php如何去除utf8的符号”,内容详细,步骤清晰,细节处理妥当,希望这篇“php如何去除utf8的符号”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。php去除utf8符号的方法:1、创建...
    99+
    2023-07-04
  • css如何去除table的间隙
    本文将为大家详细介绍“css如何去除table的间隙”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“css如何去除table的间隙”能够给你意想不到的收获,请大家跟着小编的思路慢慢深入,具体内容如下,一起去收获...
    99+
    2023-06-06
  • php如何去除多余的0
    这篇文章主要介绍php如何去除多余的0,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在php中可以直接通过“floatval()”函数去除多余的0,该函数可以保留有效的小数点,也可以去掉后面多余的0,其语法是“flo...
    99+
    2023-06-08
  • mysql如何去除空格
    小编给大家分享一下mysql如何去除空格,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! mysql去除空格的方法:1、利用replace()函数去除字...
    99+
    2024-04-02
  • javascript如何去除回车
    这篇文章主要讲解了“javascript如何去除回车”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript如何去除回车”吧! ...
    99+
    2024-04-02
  • javascript如何去除事件
    这篇文章主要介绍javascript如何去除事件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! javascript去除事件的方法:1、创建一个单击事件;...
    99+
    2024-04-02
  • php如何去除警告
    这篇文章给大家分享的是有关php如何去除警告的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。php去除警告的方法:首先打开PHP页面文件;然后在php页面的开头部分加上“ini_set("display_...
    99+
    2023-06-14
  • php如何去除括号
    这篇文章主要介绍php如何去除括号,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!php去除括号的方法:首先创建一个PHP示例文件;然后声明一个含有括号的变量;最后通过“str_replace(array( '...
    99+
    2023-06-14
  • javascript如何去除空格
    这篇文章主要介绍了javascript如何去除空格,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。JavaScript可以做什么1.可以使网页具有交互性,例如响应用户点击,给用...
    99+
    2023-06-14
  • php如何去除斜线
    这篇文章主要讲解了“php如何去除斜线”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php如何去除斜线”吧!php去除斜线的方法:首先创建一个PHP示例文件;然后通过“stripslashe...
    99+
    2023-06-20
  • jquery如何去除焦点
    这篇文章主要讲解了“jquery如何去除焦点”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jquery如何去除焦点”吧!jquery去除焦点的方法:1、通过“document.getElem...
    99+
    2023-07-05
  • 如何去除dedecms版权
    这篇文章主要介绍了如何去除dedecms版权的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何去除dedecms版权文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2023-02-21
    dedecms
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作