使用方法

context用于表示一个请求的上下文。一个网络请求,一般开启一个协程处理,而这个协程内部还会开启其它的协程继续处理。为了传递一个请求在不同协程中的处理情况(比如是否超时等),我们利用context来记录这个情况。同样的,对于一些IO处理,也需要context保存状态,比如超时时间等。

context一般用以下两种方式传递:

  • 作为函数调用的第一个参数
  • 作为一个请求结构体的可选配置
func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error){}
func (r *Request) WithContext(ctx context.Context) *Request

context应该在程序中流动,而不应该存储,不要直接存储context在结构体中等。一般来说,一个请求的contextmain中使用context.BackGorund()方法生成。一般来说,这个用于控制超时时间。

context可以继承,一旦一个context取消了,那么继承自该context的所有context都会取消,但是不会影响它的父context

context可以携带一些值,比如:

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

key必须是可比较的,而且不要是内嵌类型,自定义类型,比如:

一般来说,context携带的值应该是request-scoped类型的,即仅仅是本次请求范围内会用到的。像数据库字段之类的,不要在这里写入,因为这是全局都用的。使用context方式传递数据,会造成函数参数意义不明的情况,给出对比:

// 参数意义不明确
func IsAdminUser(ctx context.Context) bool {x := token.GetToken(ctx)userObject := auth.AuthenticateToken(x)return userObject.IsAdmin() || userObject.IsRoot()
}// 明确参数的意义,这是合理的方式
func IsAdminUser(token string, authService AuthService) int {userObject := authService.AuthenticateToken(token)return userObject.IsAdmin() || userObject.IsRoot()
}

但是,有些情况下,可以简化API的设计。比如我们有一个较长的函数调用链,向userId这种数据,却要从头到尾传递整个调用链,这不是一个好的方法。我们此时可以把这些数据封装到context中。这些数据不能是控制类型的字段,即传入函数的执行结果,最好不要依赖这些值;但是log等函数,可以打印这些数据,因为这部影响函数执行结果。

一般不建议使用context.Value的模式,这在后期重构等时候,造成一些不好的影响,除非必要,否则勿用。

使用原则和技巧:

  • 不要把Context放在结构体中,要以参数的方式传递,parent Context一般为Background
  • 应该要把Context作为第一个参数传递给入口请求和出口请求链路上的每一个函数,放在第一位,变量名建议都统一,如ctx。
  • 给一个函数方法传递Context的时候,不要传递nil,否则在tarce追踪的时候,就会断了连接
  • Context的Value相关方法应该传递必须的数据,不要什么数据都使用这个传递
  • Context是线程安全的,可以放心的在多个goroutine中传递
  • 可以把一个 Context 对象传递给任意个数的 gorotuine,对它执行取消操作时,所有 goroutine 都会接收到取消信号。

参考资料:

  • https://blog.golang.org/context
  • https://juejin.im/post/5a6873fef265da3e317e55b6
  • https://www.ardanlabs.com/blog/2019/09/context-package-semantics-in-go.html
  • http://p.agnihotry.com/post/understanding_the_context_package_in_golang/
  • https://medium.com/@cep21/how-to-correctly-use-context-context-in-go-1-7-8f2c0fafdf39

Golang的context理解相关推荐

  1. 深入理解Golang之context

    深入理解Golang之context context是Go并发编程中常用到一种编程模式.本文将从为什么需要context,深入了解context的实现原理,以了解如何使用context. 作者:Tur ...

  2. golang 上下文 Context

    上下文 context.Context Go 语言中用来设置截止日期.同步信号,传递请求相关值的结构体.上下文与 Goroutine 有比较密切的关系,是 Go 语言中独特的设计,在其他编程语言中我们 ...

  3. golang:context介绍

    我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战 1 前言 最近实现系统的分布式日志与事务管理时,在寻求所谓的全局唯一Goroutine ID无果之后,决定还是简单利用Conte ...

  4. 深入解析Golang之Context

    ​context是什么 context翻译成中文就是上下文,在软件开发环境中,是指接口之间或函数调用之间,除了传递业务参数之外的额外信息,像在微服务环境中,传递追踪信息traceID, 请求接收和返回 ...

  5. Golang中context实现原理剖析

    转载: Go 并发控制context实现原理剖析 1. 前言 Golang context是Golang应用开发常用的并发控制技术,它与WaitGroup最大的不同点是context对于派生gorou ...

  6. Golang 之context用法

    文章目录 1. context 2. context.go 2.0 结构图 2.1 Context interface 2.2 emptyCtx 2.3 cancelCtx 2.4 valueCtx ...

  7. Android中的Context理解

    1.sdk当中关于Context的介绍 Interface to global information about an application environment. This is an abs ...

  8. 【GoLang】深入理解slice len cap什么算法? 参数传递有啥蹊跷?

    先上结论 1.内置append函数在现有数组的长度 < 1024 时 cap 增长是翻倍的,再往上的增长率则是 1.25,至于为何后面会说. 2.Go语言中channel,slice,map这三 ...

  9. golang库context学习

    context库 context最早的背景说明还是来源于官方的 博客,说明如下: 在Go服务器中,每个传入请求都在其自己的goroutine中进行处理. 请求处理程序通常会启动其他goroutine来 ...

最新文章

  1. 陌陌财报双双超预期,什么才是它的基本盘?
  2. 【图像超分辨率】遥感数据的高斯金字塔尺度上推方法研究
  3. CenOS 配置C/C++语言
  4. cisco 双ISP线路接入,链路自动切换方案
  5. 【SQL】找出行数与自增标识值不相等的表(即有缺行)
  6. Intellij IDEA 配置
  7. USB 3.1 与 Type-C 接口有什么关系呢
  8. 为Windows添加日志事件
  9. 人工智能为什么不用C语言,Ai人工智能和C语言差不多吗
  10. 【Window】英文系统显示中文乱码
  11. 小米max2装鸿蒙,小米Max2最全评测 小米Max2值不值得买?
  12. 电量统计(1)-原理
  13. php 货币换算,PHP货币换算程序代码
  14. “非功能需求”属于模糊术语吗
  15. 芒果超媒前三季营收102亿:同比降12% 互联网广告收入降26%
  16. Warning: Accessing non-existent property ‘cd‘ of module exports inside circular dependency
  17. 为什么美国大城市里不修二环三环四环五环?
  18. 揭开人创造思维之谜:浴缸和床最易引发灵感
  19. 力扣121题 “买卖股票的最 佳时机”
  20. linux- 日志管理

热门文章

  1. 计算机科学与技术专业实训手册,计算机科学与技术专业实习计划
  2. pytorch学习笔记(六):softmax回归
  3. 5-2 面向可维护性的设计模式
  4. codeM 2018 资格赛
  5. IT人员及程序员怎样学好英语(关于如何利用极其有限的时间和条件学好英文)...
  6. day03 Python爬虫
  7. 第二十讲、迭代器模式
  8. spring boot 使用 websocket tomcat刚启动就关闭到问题
  9. PHP23 AJAX分页
  10. eclipse 常用设置(二)