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)    })}