您的位置:首页 > 编程语言 > Go语言

kubernetes源码之watch包until.go阅读理解四

2017-08-04 13:50 671 查看

一步一步来理解

until.go    until单词的意思conj. 在…以前;直到…时  prep. 在…以前;到…为止。那这个函数到执行到什么时候为止呢?
原文代码量几十行,内容较少,先看原始注释
// 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).
//条件:如果条件已达到,则返回true;如果尚未到达,则返回false;或错误,如果条件不能被检查,并且应该终止。
//一般来说,最好是定义水平驱动条件超过边缘驱动条件(pod状态  ready = true,对pod进行了修改,状态已经改变从false改为true)。

//有道翻译,看翻译越看越迷糊,还不如根据代码来看
type ConditionFunc func(event Event) (bool, error)

// errWatchClosed is returned when the watch channel is closed before timeout in Until.
// 当watch通道在超时之前关闭时,将返回errWatchClosed。
var errWatchClosed = errors.New("watch closed before Until timeout")

// 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.
//直到从watch中读取的数据符合每一个条件,然后返回lastwath
//遇到第一个错误就返回并且终止(同时也返回事件)。
//如果没有接收到事件,返回的事件将为nil。
//条件按顺序满足,为更高层次的构图提供一个有用的原语。(有道翻译原文)
//零超时意味着永远等待。

func Until(timeout time.Duration, watcher Interface, conditions ...ConditionFunc) (*Event, error){}
这个文件中最主要的函数,函数体先不看,函数签名中有一func类型,只看这个文件的话有些不明白func类型的具体实现,先看看谁用了Until这个函数

在common包中看有调用Until函数,当然调用Until函数的肯定有很多地方,只是用这个来举例看具体的实现,来看看是怎么调用的
event, err := watch.Until(framework.PodStartTimeout, wr, conditions.PodRunning)
第一个参数 5分钟  PodStartTimeout = 5 * time.Minute
第二个参数wr := watch.NewRecorder(w),看这个代码就能回到我们watch包中filter.go文件,具体请看我之前写的博客
func NewRecorder(w Interface) *Recorder {
r := &Recorder{}
r.Interface = Filter(w, r.record)
return r
}
第三个参数就是Until函数中的func类型了
func PodRunning(event watch.Event) (bool, error) {
switch event.Type {
case watch.Deleted:
return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "")
}
switch t := event.Object.(type) {
case *v1.Pod:
switch t.Status.Phase {
case v1.PodRunning:                  //PodRunning PodPhase = "Running"
return true, nil
case v1.PodFailed, v1.PodSucceeded:  //PodFailed PodPhase = "Failed"
return false, ErrPodCompleted
}
}
return false, nil
}


看完上面后具体在看Until函数体

func Until(timeout time.Duration, watcher Interface, conditions ...ConditionFunc) (*Event, error) {
ch := watcher.ResultChan()
defer watcher.Stop()
var after <-chan time.Time
if timeout > 0 {
after = time.After(timeout)
} else {
ch := make(chan time.Time)
defer close(ch)
after = ch
}
var lastEvent *Event
for _, condition := range conditions {
// check the next condition against the previous event and short circuit waiting for the next watch
if lastEvent != nil {
done, err := condition(*lastEvent)
if err != nil {
return lastEvent, err
}
if done {
continue
}
}
ConditionSucceeded:
for {
select {
case event, ok := <-ch:
if !ok {
return lastEvent, errWatchClosed
}
lastEvent = &event

// TODO: check for watch expired error and retry watch from latest point?
done, err := condition(event)
if err != nil {
return lastEvent, err
}
if done {
break ConditionSucceeded
}

case <-after:
return lastEvent, wait.ErrWaitTimeout
}
}
}
return lastEvent, nil
}
总结一下
一个超时时间,一个watcher,一个func类型,看看这个函数演了出什么戏。
首先做一个声称一个超时的chan,然后根据conditions判断watcher的数据。
简单的来说就是在timeout事时间内,返回watcher中不符合conditions的evnent,如果都符合的话就返回lastEvent
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  watch 源码 kubernetes