context 上下文管理

context 翻译过来就是上下文管理,主要作用有两个:

  • 控制 goroutine 的超时
  • 保存上下文数据

WithTimeout

通过下面的一个简单的 http 例子进行理解

demo:

package main

import (
"fmt"
"time"
"net/http"
"context"
"io/ioutil"
) type Result struct{
r *http.Response
err error
} func process(){
ctx,cancel := context.WithTimeout(context.Background(),2*time.Second)
defer cancel()
tr := &http.Transport{}
client := &http.Client{Transport:tr}
c := make(chan Result,1)
req,err := http.NewRequest("GET","http://www.google.com",nil)
if err != nil{
fmt.Println("http request failed,err:",err)
return
}
// 如果请求成功了会将数据存入到管道中
go func(){
resp,err := client.Do(req)
pack := Result{resp,err}
c <- pack
}() select{
case <- ctx.Done():
tr.CancelRequest(req)
fmt.Println("timeout!")
case res := <-c:
defer res.r.Body.Close()
out,_:= ioutil.ReadAll(res.r.Body)
fmt.Printf("server response:%s",out)
}
return } func main() {
process()
}

WithValue

再写一个 context 保存上下文

demo:

package main

import (
"context"
"fmt"
) func add(ctx context.Context,a,b int) int {
traceId := ctx.Value("trace_id").(string)
fmt.Printf("trace_id:%v\n",traceId)
return a+b
} func calc(ctx context.Context,a, b int) int{
traceId := ctx.Value("trace_id").(string)
fmt.Printf("trace_id:%v\n",traceId)
//再将ctx传入到add中
return add(ctx,a,b)
} func main() {
//将ctx传递到calc中
ctx := context.WithValue(context.Background(),"trace_id","123456")
ret := calc(ctx,20,30)
fmt.Printf("%d", ret)
}

运行结果:

trace_id:123456
trace_id:123456
50

WithCancel 

关于 context 官网上也有一个例子非常有用,用来控制开启的 goroutine 的退出释放

demo:

package main

import (
"context"
"fmt"
) func main() {
// gen generates integers in a separate goroutine and
// sends them to the returned channel.
// The callers of gen need to cancel the context once
// they are done consuming generated integers not to leak
// the internal goroutine started by gen.
gen := func(ctx context.Context) <-chan int {
dst := make(chan int)
n := 1
go func() {
for {
select {
case <-ctx.Done():
return // returning not to leak the goroutine
case dst <- n:
n++
}
}
}()
return dst
} ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel when we are finished consuming integers for n := range gen(ctx) {
fmt.Println(n)
if n == 5 {
break
}
}
}

WithDeadline

关于官网中的 WithDeadline 演示的代码例子

demo:

package main
import (
"context"
"fmt"
"time"
) func main() {
d := time.Now().Add(50 * time.Millisecond)
ctx, cancel := context.WithDeadline(context.Background(), d) // Even though ctx will be expired, it is good practice to call its
// cancelation function in any case. Failure to do so may keep the
// context and its parent alive longer than necessary.
defer cancel() select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err())
} }

运行结果:

context deadline exceeded

ending ~

Go context 介绍和使用的更多相关文章

  1. Golang的Context介绍及其源码分析

    简介 在Go服务中,对于每个请求,都会起一个协程去处理.在处理协程中,也会起很多协程去访问资源,比如数据库,比如RPC,这些协程还需要访问请求维度的一些信息比如说请求方的身份,授权信息等等.当一个请求 ...

  2. Tomcat下server.xml中context介绍

    conf/Context.xml是Tomcat公用的环境配置;若在server.xml中增加<Context path="/test" docBase="D:\te ...

  3. Android Context介绍

    转载(Android Context完全解析与各种获取Context方法):https://www.cnblogs.com/chenxibobo/p/6136693.html

  4. 理解Go Context机制

    1 什么是Context 最近在公司分析gRPC源码,proto文件生成的代码,接口函数第一个参数统一是ctx context.Context接口,公司不少同事都不了解这样设计的出发点是什么,其实我也 ...

  5. Android上下文Context

    Android上下文Context介绍 在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中时刻的在与它打交道,例如:Service.BroadcastReceiv ...

  6. Golang 高效实践之并发实践context篇

    前言 在上篇Golang高效实践之并发实践channel篇中我给大家介绍了Golang并发模型,详细的介绍了channel的用法,和用select管理channel.比如说我们可以用channel来控 ...

  7. Go实现海量日志收集系统(三)

    再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagent etcd介绍 高可用的分布式 ...

  8. Flask类的属性和方法大全

    Flask Property__class____dict____doc____module__app_ctx_globals_classconfig_classdebugdefault_config ...

  9. OpenGL Windows 窗口程序环境搭建

    OpenGL环境搭建步骤: Downloading OpenGL 根据官网的说法: In all three major desktop platforms (Linux, macOS, and Wi ...

随机推荐

  1. Access 字段拼接(UPDATE 数据追加)

    今天遇到一个需求,在Access数据库中,有个net_id 字段,它的值是由 “jjgrape” 这个字符串和 id 字段组成的,也就是说,要把 ‘jjgrape’ 和 id 字段拼接起来: 那怎么拼 ...

  2. Python记录-python执行shell命令

    # coding=UTF-8 import os def distcp(): nncheck = os.system('lsof -i:8020') dncheck = os.system('lsof ...

  3. cookie加载不正确的问题

    华为系统更新后安装了一个谷歌6月安全补丁的东西,然后之前写的调h5页面的部分就出现了问题,后台查过发现是Android端调h5页面时cookie没能带过去,导致了登录失败.于是对setCookie部分 ...

  4. 实现不同的项目,用不同的git 账号提交

    可以全局配置一个git 账户名和密码,然后在具体项目里单独配置一个账户名和密码 例如: git config --global user.name "winyh" git conf ...

  5. 【分布式一致性】etcd

    etcd: https://jimmysong.io/kubernetes-handbook/concepts/etcd.html 什么是 分布式一致性: http://thesecretliveso ...

  6. HDU 2089 不要62 数位DP模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 参考博客:https://www.cnblogs.com/HDUjackyan/p/914215 ...

  7. <统计学>统计学开篇

    我们或多多少都接触学习过统计学,可统计学到底是一种什么样的学科呢? 我们将统计学定义为:对数据进行收集.整理.展示.分析和解释,以帮助人们更有效地进行决策的科学. 关于统计学的研究通常分为两类:描述统 ...

  8. 台式电脑Bios界面设置U盘启动

  9. C# RESTful API

    C# RESTful API REST 全称是 Representational State Transfer,有人说它是一种风格,并非一种标准,个人觉得挺有道理.它本身并没有创造新的技术.组件与服务 ...

  10. Java中关于时间日期格式保存到mysql的问题

    首先在设置数据库的时间日期字段的时候要先确定好采用何种类型,DATETIME. TIMESTAMP.DATE.TIME.YEAR. 其中datetime.time用的比较多,对应java中生成的poj ...