工厂
我们先定义了一个工厂接口,此接口InformerFor函数是构造某个资源的SharedIndexInformer需要知道资源以及构造这个资源SharedIndexInformer的方法,有点绕,大概意思就是这个函数其实不知道怎么构造资源的SharedIndexInformer,都是需要入参提供的,自身是非常的通用。
1
2
3
4
5
6
7
8
| type FactoryI interface {
InformerFor(resource any, constructF ConstructFuncForInformerI) SharedIndexInformer
}
type SharedIndexInformer interface {
// 包含很多方法,具体是什么方法后面再说
}
type ConstructFuncForInformerI func(client http.Client) SharedIndexInformer
|
我们再来看FactoryI的实现,聚焦于InformerFor函数,如上讨论,这个里面没有具体某个资源SharedIndexInformer生成逻辑,只是有一个缓存。这里好处如下:
- 当某个资源调用过一次InformerFor后,后续再调用就可以直接从缓存中拿就行了。
- 可以记录所有生成过SharedIndexInformer的资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| type Factory struct {
cache map[reflect.Type]SharedIndexInformer
client http.Client
}
func (f *Factory) InformerFor(resource any, constructF ConstructFuncForInformerI) SharedIndexInformer {
curType := reflect.TypeOf(resource)
if v, ok := f.cache[curType]; ok {
return v
} else {
f.cache[curType] = constructF(f.client)
return f.cache[curType]
}
}
|
那么Factory的InformerFor方法再哪里被调用呢?
继续来看Factory的另一个方法,它是用户自己定义的一个资源(可类比与deployment,pod等),它的响应是一个组方法,继续跟踪下去可以看到有版本,然后是Informer,这个Informer有Informer方法以及一个私有的构造SharedIndexInformer接口的方法。
而且工厂自身也被依次的传递了下去,直到Informer函数里调用了工厂的InformerFor方法。
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
| func (f *Factory) 我自己定义的资源() GroupInterfaceI {
return NewGroupInterface(f)
}
type GroupInterfaceI interface {
V1ByXXX() VersionInterfaceI
}
func NewGroupInterface(f FactoryI) GroupInterfaceI {
return &GroupInterface{
f: f,
}
}
type GroupInterface struct {
f FactoryI
}
func (g *GroupInterface) V1ByXXX() VersionInterfaceI {
return NewVersionInterface(g.f)
}
type VersionInterfaceI interface {
KindByXXX() XXXInformerI
}
func NewVersionInterface(f FactoryI) VersionInterfaceI {
return &VersionInterface{
f: f,
}
}
type VersionInterface struct {
f FactoryI
}
func (g *VersionInterface) KindByXXX() XXXInformerI {
return NewXXXInformer(g.f)
}
type 我自己定义的资源InformerI interface {
Informer() SharedIndexInformer
}
func New我自己定义的资源Informer(f FactoryI) XXXInformerI {
return &XXXInformer{
factory: f,
}
}
type 我自己定义的资源Informer struct {
factory FactoryI
}
func (x *我自己定义的资源Informer) Informer() SharedIndexInformer {
return x.factory.InformerFor(我自己定义的资源Informer{}, x.defaultInformer)
}
func (x *我自己定义的资源Informer) defaultInformer(client http.Client) SharedIndexInformer {
// panic("implement me")
return nil
}
var _ ConstructFuncForInformerI = 我自己定义的资源Informer{}.defaultInformer
|
到这里也就看明白了Factory方法以及Factory具体实现以及自定义资源的Informer的大致调用过程。资源对应的SharedIndexInformer还是由自身来决定怎么实现。工厂只是提供了InformerFor方法,来缓存所有资源的SharedIndexInformer。