kubernetes源码之watch包mux.go阅读理解二

本文详细探讨了kubernetes中watch包的mux.go文件,从总结、定义常量、广播器数据结构、创建及方法到广播器watcher的工作原理,全面解析了watch机制的关键实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结

此文件中主要有两个数据结构,一个广播器,一个是广播器wathcer
广播器实现的方法:
func (b *Broadcaster) blockQueue(f func())  
func (m *Broadcaster) Watch() Interface        向广播器中添加一个wathcer
func (m *Broadcaster) WatchWithPrefix(queuedEvents []Event) Interface  向广播器中添加一个有事件的wathcer
func (m *Broadcaster) stopWatching(id int64)     删除广播器中指定ID的watcher
func (m *Broadcaster) closeAll()    关闭所有watcher的result管道,并且清空广播器中的watcher
func (m *Broadcaster) loop()  将incoming的事件分发给watcher(具体分发由下一行实现)
func (m *Broadcaster) distribute(event Event)  具体分发给所有watcher的具体实现(对loop中分发的实现)
func (m *Broadcaster) Shutdown()
广播器wathcer只是具体对Interface的实现

定义常量

const incomingQueueLength = 25
type FullChannelBehavior int
const (
    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 chan
func (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处理完
//不能添加新的event
func (m *Broadcaster) Shutdown() {
    close(m.incoming)
    m.distributing.Wait()
}

//分发事件给所有的watcher
func (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)
    })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值