JOE'S BLOG

好记性不如烂键盘

0%

go web从入门到精通

简介

本文将从context->http->gin的路线全面吃透go web开发

context

要理解go web开发我认为首先离不开的就是context, 同时context也是最适合用来学习go源码的一个包

几种ctx的简介

  1. emptyCtx: 所有ctx的根,用context.TODO(), context.Background()生成
  2. valueCtx: 在ctx中存储kv数据,同一个ctx只能存储一个kv数据, 更多的kv数据构造了一个树形结构
  3. cancelCtx: 可以用来取消程序的执行树, 父级取消会依次通知下级取消所有的ctx, 也是最为核心实现最复杂的一个ctx
  4. timerCtx: 基于cancelCtx,基于支持时间的cancel

context的核心接口,有以下几个方法, 上面的几个ctx也都是围绕该接口实现和扩展的

1
2
3
4
5
6
7
8
// Context's methods may be called by multiple goroutines simultaneously.
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key any) any
}

emptyCtx

emptyCtx是所有ctx的根,一般通过context.TODO()和context.Background()来使用, 通过代码也都是可以看到最终都是new(emptyCtx)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int

var (
background = new(emptyCtx)
todo = new(emptyCtx)
)

// Background returns a non-nil, empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
// requests.
func Background() Context {
return background
}

// TODO returns a non-nil, empty Context. Code should use context.TODO when
// it's unclear which Context to use or it is not yet available (because the
// surrounding function has not yet been extended to accept a Context
// parameter).
func TODO() Context {
return todo
}

硬要说区别的话,在调用String方法的时候输出的值会不一样。emptyCtx可以看到其实现的方法都是空的

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
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int

func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return
}

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

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

func (*emptyCtx) Value(key any) any {
return nil
}

func (e *emptyCtx) String() string {
switch e {
case background:
return "context.Background"
case todo:
return "context.TODO"
}
return "unknown empty Context"
}

http

gin

参考文献