Implement Cacher for watch in apiserver
This commit is contained in:
24
pkg/client/cache/reflector.go
vendored
24
pkg/client/cache/reflector.go
vendored
@@ -170,30 +170,27 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) {
|
||||
return t.C, t.Stop
|
||||
}
|
||||
|
||||
func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) {
|
||||
// Returns error if ListAndWatch didn't even tried to initialize watch.
|
||||
func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
|
||||
var resourceVersion string
|
||||
resyncCh, cleanup := r.resyncChan()
|
||||
defer cleanup()
|
||||
|
||||
list, err := r.listerWatcher.List()
|
||||
if err != nil {
|
||||
util.HandleError(fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err))
|
||||
return
|
||||
return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err)
|
||||
}
|
||||
meta, err := meta.Accessor(list)
|
||||
if err != nil {
|
||||
util.HandleError(fmt.Errorf("%s: Unable to understand list result %#v", r.name, list))
|
||||
return
|
||||
return fmt.Errorf("%s: Unable to understand list result %#v", r.name, list)
|
||||
}
|
||||
resourceVersion = meta.ResourceVersion()
|
||||
items, err := runtime.ExtractList(list)
|
||||
if err != nil {
|
||||
util.HandleError(fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err))
|
||||
return
|
||||
return fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err)
|
||||
}
|
||||
if err := r.syncWith(items, resourceVersion); err != nil {
|
||||
util.HandleError(fmt.Errorf("%s: Unable to sync list result: %v", r.name, err))
|
||||
return
|
||||
return fmt.Errorf("%s: Unable to sync list result: %v", r.name, err)
|
||||
}
|
||||
r.setLastSyncResourceVersion(resourceVersion)
|
||||
|
||||
@@ -220,13 +217,13 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if err := r.watchHandler(w, &resourceVersion, resyncCh, stopCh); err != nil {
|
||||
if err != errorResyncRequested && err != errorStopRequested {
|
||||
glog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedType, err)
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,6 +274,7 @@ loop:
|
||||
util.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event))
|
||||
continue
|
||||
}
|
||||
newResourceVersion := meta.ResourceVersion()
|
||||
switch event.Type {
|
||||
case watch.Added:
|
||||
r.store.Add(event.Object)
|
||||
@@ -290,8 +288,8 @@ loop:
|
||||
default:
|
||||
util.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event))
|
||||
}
|
||||
*resourceVersion = meta.ResourceVersion()
|
||||
r.setLastSyncResourceVersion(*resourceVersion)
|
||||
*resourceVersion = newResourceVersion
|
||||
r.setLastSyncResourceVersion(newResourceVersion)
|
||||
eventCount++
|
||||
}
|
||||
}
|
||||
|
17
pkg/client/cache/watch_cache.go
vendored
17
pkg/client/cache/watch_cache.go
vendored
@@ -123,13 +123,20 @@ func objectToVersionedRuntimeObject(obj interface{}) (runtime.Object, uint64, er
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
resourceVersion, err := strconv.ParseUint(meta.ResourceVersion(), 10, 64)
|
||||
resourceVersion, err := parseResourceVersion(meta.ResourceVersion())
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return object, resourceVersion, nil
|
||||
}
|
||||
|
||||
func parseResourceVersion(resourceVersion string) (uint64, error) {
|
||||
if resourceVersion == "" {
|
||||
return 0, nil
|
||||
}
|
||||
return strconv.ParseUint(resourceVersion, 10, 64)
|
||||
}
|
||||
|
||||
func (w *WatchCache) processEvent(event watch.Event, resourceVersion uint64, updateFunc func(runtime.Object) error) error {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
@@ -186,7 +193,7 @@ func (w *WatchCache) Replace(objs []interface{}) error {
|
||||
}
|
||||
|
||||
func (w *WatchCache) ReplaceWithVersion(objs []interface{}, resourceVersion string) error {
|
||||
version, err := strconv.ParseUint(resourceVersion, 10, 64)
|
||||
version, err := parseResourceVersion(resourceVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -227,15 +234,15 @@ func (w *WatchCache) GetAllEventsSince(resourceVersion uint64) ([]watch.Event, e
|
||||
if size > 0 {
|
||||
oldest = w.cache[w.startIndex%w.capacity].resourceVersion
|
||||
}
|
||||
if resourceVersion < oldest {
|
||||
return nil, fmt.Errorf("too old resource version: %d (%d)", resourceVersion, oldest)
|
||||
}
|
||||
|
||||
// Binary seatch the smallest index at which resourceVersion is not smaller than
|
||||
// the given one.
|
||||
f := func(i int) bool {
|
||||
return w.cache[(w.startIndex+i)%w.capacity].resourceVersion >= resourceVersion
|
||||
}
|
||||
if size > 0 && resourceVersion < oldest {
|
||||
return nil, fmt.Errorf("too old resource version: %d (%d)", resourceVersion, oldest)
|
||||
}
|
||||
first := sort.Search(size, f)
|
||||
result := make([]watch.Event, size-first)
|
||||
for i := 0; i < size-first; i++ {
|
||||
|
Reference in New Issue
Block a user