目录

gin-context的使用

概述

下面是一个 context 的使用方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package main

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"time"
)

type YuerContext struct {
	context.Context
	Gin *gin.Context
}

type YuerHandleFunc func(c *YuerContext)

func WithYuerContext(yuerHandle YuerHandleFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println(<-chan struct{}(nil))

		// 可以在gin.Context中设置key-value
		c.Set("trace", "假设这是一个调用链追踪sdk")

		// 全局超时控制
		timeoutCtx, cancelFunc := context.WithTimeout(c, 5*time.Second)
		defer cancelFunc()

		// ZDM上下文
		yuerCtx := YuerContext{Context: timeoutCtx, Gin: c}

		// 回调接口
		yuerHandle(&yuerCtx)
	}
}

// 模拟一个MYSQL查询
func dbQuery(ctx context.Context, sql string) {
	// 模拟调用链埋点
	trace := ctx.Value("trace").(string)

	// 模拟长时间逻辑阻塞, 被context的5秒超时中断
	<-ctx.Done()

	fmt.Println(trace)
}

func main() {
	r := gin.New()

	r.GET("/test", WithYuerContext(func(c *YuerContext) {
		// 业务层处理
		dbQuery(c, "select * from xxx")
		// 调用gin应答
		c.Gin.String(200, "请求完成")
	}))

	r.Run()
}

参考资料

警告
本文最后更新于 2021年6月30日,文中内容可能已过时,请谨慎参考。