kubernetes源码之watch包mux.go阅读理解二
来源:互联网 发布:数据帧结构 编辑:程序博客网 时间:2024/05/21 10:30
总结
此文件中主要有两个数据结构,一个广播器,一个是广播器wathcer广播器实现的方法:func (b *Broadcaster) blockQueue(f func()) func (m *Broadcaster) Watch() Interface 向广播器中添加一个wathcerfunc (m *Broadcaster) WatchWithPrefix(queuedEvents []Event) Interface 向广播器中添加一个有事件的wathcerfunc (m *Broadcaster) stopWatching(id int64) 删除广播器中指定ID的watcherfunc (m *Broadcaster) closeAll() 关闭所有watcher的result管道,并且清空广播器中的watcherfunc (m *Broadcaster) loop() 将incoming的事件分发给watcher(具体分发由下一行实现)func (m *Broadcaster) distribute(event Event) 具体分发给所有watcher的具体实现(对loop中分发的实现)func (m *Broadcaster) Shutdown()广播器wathcer只是具体对Interface的实现
定义常量
const incomingQueueLength = 25type FullChannelBehavior intconst ( WaitIfChannelFull FullChannelBehavior = iota DropIfChannelFull)
广播器数据结构
type Broadcaster struct { // TODO: see if this lock is needed now that new watchers go through // the incoming channel. lock sync.Mutex watchers map[int64]*broadcasterWatcher nextWatcher int64 distributing sync.WaitGroup incoming chan Event watchQueueLength int fullChannelBehavior FullChannelBehavior }
创建一个广播器
func NewBroadcaster(queueLength int, fullChannelBehavior FullChannelBehavior) *Broadcaster { m := &Broadcaster{ watchers: map[int64]*broadcasterWatcher{}, incoming: make(chan Event, incomingQueueLength), watchQueueLength: queueLength, fullChannelBehavior: fullChannelBehavior, } m.distributing.Add(1) go m.loop() return m}
广播器的全部方法
//执行f,阻塞传入队列(并等待它先排空)。//他的目的是让watch在事件发生后再添加一个事件,并且在他们被添加之后总是会看到任何新进来的事件//添加一个空的event事件,阻塞管道,添加watch的时候不允许向incomming中写入数据func (b *Broadcaster) blockQueue(f func()) { var wg sync.WaitGroup wg.Add(1) b.incoming <- Event{ Type: internalRunFunctionMarker, Object: functionFakeRuntimeObject(func() { defer wg.Done() f() }), } wg.Wait()}//添加一个新的watcher//新的watcher只能接收新的事件,不会得到之前的事件func (m *Broadcaster) Watch() Interface { var w *broadcasterWatcher m.blockQueue(func() { m.lock.Lock() defer m.lock.Unlock() id := m.nextWatcher m.nextWatcher++ w = &broadcasterWatcher{ result: make(chan Event, m.watchQueueLength), stopped: make(chan struct{}), id: id, m: m, } m.watchers[id] = w }) return w}//添加一个有事件的watch,疑问:多个事件写入result管道是否会报错?//仔细阅读代码会有结果,result的长度是在new的时候初始化的func (m *Broadcaster) WatchWithPrefix(queuedEvents []Event) Interface { var w *broadcasterWatcher m.blockQueue(func() { m.lock.Lock() defer m.lock.Unlock() id := m.nextWatcher m.nextWatcher++ length := m.watchQueueLength if n := len(queuedEvents) + 1; n > length { length = n } w = &broadcasterWatcher{ result: make(chan Event, length), stopped: make(chan struct{}), id: id, m: m, } m.watchers[id] = w for _, e := range queuedEvents { w.result <- e } }) return w}//删除指定id的watcher,关闭对应的result chanfunc (m *Broadcaster) stopWatching(id int64) { m.lock.Lock() defer m.lock.Unlock() w, ok := m.watchers[id] if !ok { // No need to do anything, it's already been removed from the list. return } delete(m.watchers, id) close(w.result)}//关闭所有的wathcer的result,重置广播器的wathers(即清空)func (m *Broadcaster) closeAll() { m.lock.Lock() defer m.lock.Unlock() for _, w := range m.watchers { close(w.result) } // Delete everything from the map, since presence/absence in the map is used // by stopWatching to avoid double-closing the channel. m.watchers = map[int64]*broadcasterWatcher{}}//向广播器中添加事件func (m *Broadcaster) Action(action EventType, obj runtime.Object) { m.incoming <- Event{action, obj}}//关闭incoming,广播器停止接受事件//incoming中的event任然会进行分发给所有watcher,会等待所有的event处理完//不能添加新的eventfunc (m *Broadcaster) Shutdown() { close(m.incoming) m.distributing.Wait()}//分发事件给所有的watcherfunc (m *Broadcaster) loop() { // Deliberately not catching crashes here. Yes, bring down the process if there's a // bug in watch.Broadcaster. for { event, ok := <-m.incoming if !ok { break } if event.Type == internalRunFunctionMarker { event.Object.(functionFakeRuntimeObject)() continue } m.distribute(event) } m.closeAll() m.distributing.Done()}//分发事件的具体方法func (m *Broadcaster) distribute(event Event) { m.lock.Lock() defer m.lock.Unlock() if m.fullChannelBehavior == DropIfChannelFull { for _, w := range m.watchers { select { case w.result <- event: case <-w.stopped: default: // Don't block if the event can't be queued. } } } else { for _, w := range m.watchers { select { case w.result <- event: case <-w.stopped: } } }}
广播器watcher
//只是对Interface的一个实现//广播器watcher数据结构中包含广播器字段,只是为了调用广播器的方法,从广播器中删除自己type broadcasterWatcher struct { result chan Event stopped chan struct{} stop sync.Once id int64 m *Broadcaster}// ResultChan returns a channel to use for waiting on events.func (mw *broadcasterWatcher) ResultChan() <-chan Event { return mw.result}// Stop stops watching and removes mw from its list.func (mw *broadcasterWatcher) Stop() { mw.stop.Do(func() { close(mw.stopped) mw.m.stopWatching(mw.id) })}
阅读全文
0 0
- kubernetes源码之watch包mux.go阅读理解二
- kubernetes源码之watch包watch.go阅读理解一
- kubernetes源码之watch包filter.go阅读理解三
- kubernetes源码之watch包until.go阅读理解四
- kubernetes源码之watch包streamwatcher.go阅读理解五
- kubernetes源码阅读之kubelet(二)
- kubernetes源码阅读之controller-manager(二)
- kubernetes源码阅读之apiserver
- kubernetes list-watch(二)
- kubernetes源码阅读之整体架构分析
- kubernetes源码阅读之kubelet启动
- kubernetes源码阅读之controller manager启动
- kubernetes watch的使用源码
- kubernetes 源码分析之kubeadm(二)
- kubernetes 源码分析之ingress(二)
- kubernetes源码阅读之kubelet pod之来源
- kubernetes源码阅读之controller-manager(三)
- nsq源码阅读 nsqlookupd源码二 registration_db.go
- 网易微专业 前端工程师 学习笔记
- lombok插件简介
- 20岁生日
- WPF DocumentViewer控件报表去掉不必要的工具按钮
- UVA10815 Andy's First Dictionary(字符串)
- kubernetes源码之watch包mux.go阅读理解二
- javascript获取form表单中的字段值
- SQL学习笔记--2
- 零基础APP自动化测试教程(三)
- codeforces 779B Weird Rounding
- MT7628/MT7688平台上如何配置任何一个管脚为GPIO模式,试用各种平台
- python第三方库pandas和lxml
- string 直接定义字符
- 一、机器学习初起步