You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// EventType defines the possible types of events.typeEventTypestringconst (
AddedEventType="ADDED"ModifiedEventType="MODIFIED"DeletedEventType="DELETED"ErrorEventType="ERROR"DefaultChanSizeint32=100
)
// Event represents a single event to a watched resource.// +k8s:deepcopy-gen=truetypeEventstruct {
TypeEventType// Object is:// * If Type is Added or Modified: the new state of the object.// * If Type is Deleted: the state of the object immediately before deletion.// * If Type is Error: *api.Status is recommended; other types may make sense// depending on context.Object runtime.Object
}
// Interface can be implemented by anything that knows how to watch and report changes.typeInterfaceinterface {
// Stops watching. Will close the channel returned by ResultChan(). Releases// any resources used by the watch.Stop()
// Returns a chan which will receive all the events. If an error occurs// or Stop() is called, this channel will be closed, in which case the// watch should be completely cleaned up.ResultChan() <-chanEvent
}
typeemptyWatchchanEvent// NewEmptyWatch returns a watch interface that returns no results and is closed.// May be used in certain error conditions where no information is available but// an error is not warranted.funcNewEmptyWatch() Interface {
ch:=make(chanEvent)
close(ch)
returnemptyWatch(ch)
}
// FakeWatcher lets you test anything that consumes a watch.Interface; threadsafe.typeFakeWatcherstruct {
resultchanEventStoppedbool
sync.Mutex
}
funcNewFake() *FakeWatcher {
return&FakeWatcher{
result: make(chanEvent),
}
}
funcNewFakeWithChanSize(sizeint, blockingbool) *FakeWatcher {
return&FakeWatcher{
result: make(chanEvent, size),
}
}
// RaceFreeFakeWatcher lets you test anything that consumes a watch.Interface; threadsafe.typeRaceFreeFakeWatcherstruct {
resultchanEventStoppedbool
sync.Mutex
}
funcNewRaceFreeFake() *RaceFreeFakeWatcher {
return&RaceFreeFakeWatcher{
result: make(chanEvent, DefaultChanSize),
}
}
// Broadcaster distributes event notifications among any number of watchers. Every event// is delivered to every watcher.typeBroadcasterstruct {
// TODO: see if this lock is needed now that new watchers go through// the incoming channel.lock sync.Mutexwatchersmap[int64]*broadcasterWatchernextWatcherint64distributing sync.WaitGroupincomingchanEvent// How large to make watcher's channel.watchQueueLengthint// If one of the watch channels is full, don't wait for it to become empty.// Instead just deliver it to the watchers that do have space in their// channels and move on to the next event.// It's more fair to do this on a per-watcher basis than to do it on the// "incoming" channel, which would allow one slow watcher to prevent all// other watchers from getting new events.fullChannelBehaviorFullChannelBehavior
}
// NewBroadcaster creates a new Broadcaster. queueLength is the maximum number of events to queue per watcher.// It is guaranteed that events will be distributed in the order in which they occur,// but the order in which a single event is distributed among all of the watchers is unspecified.funcNewBroadcaster(queueLengthint, fullChannelBehaviorFullChannelBehavior) *Broadcaster {
m:=&Broadcaster{
watchers: map[int64]*broadcasterWatcher{},
incoming: make(chanEvent, incomingQueueLength),
watchQueueLength: queueLength,
fullChannelBehavior: fullChannelBehavior,
}
m.distributing.Add(1)
gom.loop()
returnm
}
broadcasterWatcher struct
broadcasterWatcher实现了watch.Interface interface
// broadcasterWatcher handles a single watcher of a broadcastertypebroadcasterWatcherstruct {
resultchanEventstoppedchanstruct{}
stop sync.Onceidint64m*Broadcaster
}
// FilterFunc should take an event, possibly modify it in some way, and return// the modified event. If the event should be ignored, then return keep=false.typeFilterFuncfunc(inEvent) (outEvent, keepbool)
funcFilter(wInterface, fFilterFunc) Interface {
fw:=&filteredWatch{
incoming: w,
result: make(chanEvent),
f: f,
}
gofw.loop()
returnfw
}
typefilteredWatchstruct {
incomingInterfaceresultchanEventfFilterFunc
}
// Recorder records all events that are sent from the watch until it is closed.typeRecorderstruct {
Interfacelock sync.Mutexevents []Event
}
var_Interface=&Recorder{}
// NewRecorder wraps an Interface and records any changes sent across it.funcNewRecorder(wInterface) *Recorder {
r:=&Recorder{}
r.Interface=Filter(w, r.record)
returnr
}
// record is a FilterFunc and tracks each received event.func (r*Recorder) record(inEvent) (Event, bool) {
r.lock.Lock()
deferr.lock.Unlock()
r.events=append(r.events, in)
returnin, true
}
// Decoder allows StreamWatcher to watch any stream for which a Decoder can be written.typeDecoderinterface {
// Decode should return the type of event, the decoded object, or an error.// An error will cause StreamWatcher to call Close(). Decode should block until// it has data or an error occurs.Decode() (actionEventType, object runtime.Object, errerror)
// Close should close the underlying io.Reader, signalling to the source of// the stream that it is no longer being watched. Close() must cause any// outstanding call to Decode() to return with an error of some sort.Close()
}
// StreamWatcher turns any stream for which you can write a Decoder interface// into a watch.Interface.typeStreamWatcherstruct {
sync.MutexsourceDecoderresultchanEventstoppedbool
}
// NewStreamWatcher creates a StreamWatcher from the given decoder.funcNewStreamWatcher(dDecoder) *StreamWatcher {
sw:=&StreamWatcher{
source: d,
// It's easy for a consumer to add buffering via an extra// goroutine/channel, but impossible for them to remove it,// so nonbuffered is better.result: make(chanEvent),
}
gosw.receive()
returnsw
}
until.go
Until用于满足conditions条件的watcher的Event过滤
// ConditionFunc returns true if the condition has been reached, false if it has not been reached yet,// or an error if the condition cannot be checked and should terminate. In general, it is better to define// level driven conditions over edge driven conditions (pod has ready=true, vs pod modified and ready changed// from false to true).typeConditionFuncfunc(eventEvent) (bool, error)
// Until reads items from the watch until each provided condition succeeds, and then returns the last watch// encountered. The first condition that returns an error terminates the watch (and the event is also returned).// If no event has been received, the returned event will be nil.// Conditions are satisfied sequentially so as to provide a useful primitive for higher level composition.// A zero timeout means to wait forever.funcUntil(timeout time.Duration, watcherInterface, conditions...ConditionFunc) (*Event, error) {}
The text was updated successfully, but these errors were encountered:
介绍
我们一起来研究下kubernetes的watch包,这有助于理解kubernetes的list-watch机制,本文基于v1.9.7,代码目录
/vendor/k8s.io/apimachinery/pkg/watch
watch.go
watch.go定义了Event结构体和watch.Interface接口
Event struct
Event struct
包括事件类型Type
和事件发生的对象Object
watch.Interface interface
watch.Interface
包括两个方法:返回事件监听结果的chanResultChan()
和停止监听的方法Stop()
watch.go还包括三种Interface实现:
emptyWatch
,FakeWatcher
,RaceFreeFakeWatcher
,其中FakeWatcher和RaceFreeFakeWatcher是线程安全的mux.go
mux.go主要包括事件广播器
Broadcaster
和广播器观察者broadcasterWatcher
Broadcaster struct
Broadcaster包括一个watchers map,Broadcaster有一个协程接收所有的事件并发送事件到所有注册的watcher。保证Broadcaster的所有watcher一直都能不断的接收到Broadcaster发送过来的事件
broadcasterWatcher struct
broadcasterWatcher
实现了watch.Interface interfacefilter.go
filteredWatch struct
filteredWatch
实现了watch.Interface interface,通过FilterFunc
可以只watch满足一定条件的事件Recorder struct
Recorder结构体中的Interface是filteredWatch,记录watcher所接收到的所有的事件
streamwatcher.go
StreamWatcher
封装一个实现Decoder
interface的stream,将其转换为watch.Interface实现until.go
Until
用于满足conditions条件的watcher的Event过滤The text was updated successfully, but these errors were encountered: