- informerFactory 相当于工厂模式,它可以存放多个informer,每个informer 主要包含几个关键元素:
- indexer 一个cashe 缓存
- processor: Processor 存放了多个listener
- listWatcher : list 和 watch 对应对象的数据
- crontroller: controller 里主要包含: listwatch,deltaFifo的队列,还有一个process
- 每个informer 都可以添加Event,AddEvent操作,AddEvent 的参数是一个EventHandler,里面包含了AddFunction, UpdateFunction, DeleteFunction, 其最终的目的,是将informer ListAddWatch过来的数据 通过这三个Function,传递给外部对象
- informer 每次add 一个Event时候,都会创建一个listener 然后放到Processor 里, listener 里面主要包含了几个关键要素:
- nextCh 和 addCh 的chan (无缓冲的chan) 以及 EventHandler,
- listener 创建后, 会启动listener 的run 和pop 功能, pop的实现:
- pop 的核心原理是将addCh chan里的数据转到nextCh channnel 中
- run 的实现, run是连接数据到Hander的转折点
- run 将nextCh 中的数据,取出来, 根据这个数据里的type 来判断是update,Add 还是Delete,然后执行handler 里的 AddFunction, UpdateFunction, DeleteFunction ,最终将数据转给了外部对象
- 那么 addCh 数据是怎么来的? 最终又如何通过 AddFunction, UpdateFunction, DeleteFunction 转给了外部对象呢
- addCh 的由来:
- 最上层的InformerFactory 创建后,在通过添加各种Informer后(具体添加Informer的例子: s.InformerFactory.Core().V1().Nodes() 这是添加node 的Informer), 在最后会调用start 方法:
- start 核心逻辑是 调用里面每个Informer 的run 方法
- 每个Informer 的run 方法:可以说Informer的run 方法是一个生产者
- 在run 方法里,会创建一个DeltaFIFO 的队列,
- 会对controller 进行赋值, 将listwatch,deltafifo 赋值进去,另外是定义Process 方法。
- Process 方法的核心处理逻辑,是讲传给来的数据 1 更新informer 的indexr缓存。 2 是调用informer 的process 字段的distribute方法,distribute 方法的核心逻辑,是调用里面每个listener的add 方法,将数据放到 AddCh 的channel 中
- 之后Informer 会调用自己元素:process 的run方法,上面已经知道process 存放了很多listener, process 的run 方法是,通过go协程,执行每个listener 的run 和pop 方法,listener 的pop 和run 最终的目的是会将Informer得到的数据 传递给外部对象
- 接下来是最重要的control的run 方法,controller 是一个联系纽带,它的目的是通过一个机制,将listwatch 出来的数据,给每个listener 的 addCh 的channnel, 具体逻辑如下:
- 执行control 的run 方法后,会创建一个reflect的对象,reflect对象 主要保存了两个字段,一个是listwatch 另一个是 fifo 的队列,之后reflect 对象会执行run方法,核心逻辑就是调用apiserve的list and watch 方法,把数据放到fifo 的队列中
- 之后control 会执行 processLoop方法 这个loop方法 ,核心逻辑是不断的将fifo 队列中的数据pop出来,而pop出来的数据是给 control 的Process 字段代表的方法去处理。而Process 在上面也说了,正好是调用里面所有listener 的distribute 方法,将数据分发到每个listener 的addCh 字段中。
- 最上层的InformerFactory 创建后,在通过添加各种Informer后(具体添加Informer的例子: s.InformerFactory.Core().V1().Nodes() 这是添加node 的Informer), 在最后会调用start 方法:
- 这样整个流程就跑通了,reflect 将apiserver 获得的数据放到fifo 队列中, controller的ProcessLoop方法,不断的将数据Pop 出来,给controller 的Process 去处理,Process 主要是讲获得的数据分发到informer的各个listener 的addCh channel 中,而每个listener都会执行pop 和run 操作,Pop 是讲addCh channel的数据转给nextCh 的channel 中, 而run 操作 是讲nextCh的数据取出来,最终调用AddFunction,或者UpdateFunction,或者DeleteFunction,之后就转给了外部对象,而这个三个function 是怎么转给外部对象的呢,一般情况下这外部对象一般也是一个cacher,如scheduler 会创建一个schedulercache, 而schedulercache会有对应的 AddFunction,或者UpdateFunction,或者DeleteFunction ,之后会将这些数据扔到新cache中
-