概要
在k8s的源码或者开源项目中,onDelete事件是经常出现,处理方法也具有一定的规律,其中用到了cache.DeletedFinalStateUnknown,它是什么?有什么作用?
onDelete 常规流程
func onDelete(obj interface{}) {
apiObject, ok := obj.(*APIObject)
if !ok {
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
if !ok {
return
}
apiObject, ok := tombstone.Obj.(*APIObject)
if !ok {
return
}
}
}
看起来,这段流程有点怪异,为什么额外进行了2次Type断言?这种时候,直接看k8s源码,会发现非常简单。 首先找到cache.DeletedFinalStateUnknown的定义:
// DeletedFinalStateUnknown is placed into a DeltaFIFO in the case where an object
// was deleted but the watch deletion event was missed while disconnected from
// apiserver. In this case we don't know the final "resting" state of the object, so
// there's a chance the included `Obj` is stale.
type DeletedFinalStateUnknown struct {
Key string
Obj interface{}
}
原来,它就是把一个Object放入了Obj变量中,保存了那些已经被删除的对象,作为一种cache,避免获取不到这个对象了。 而它的用法,在cache包中也只出现了2次,在同一个函数中:
func (f *DeltaFIFO) Replace(list []interface{}, _ string) error {
if f.knownObjects == nil {
// Do deletion detection against our own list.
queuedDeletions := 0
for k, oldItem := range f.items {
if keys.Has(k) {
continue
}
// Delete pre-existing items not in the new list.
// This could happen if watch deletion event was missed while
// disconnected from apiserver.
var deletedObj interface{}
if n := oldItem.Newest(); n != nil {
deletedObj = n.Object
}
queuedDeletions++
if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil {
return err
}
}
}
// Detect deletions not already in the queue.
knownKeys := f.knownObjects.ListKeys()
queuedDeletions := 0
for _, k := range knownKeys {
if keys.Has(k) {
continue
}
deletedObj, exists, err := f.knownObjects.GetByKey(k)
if err != nil {
deletedObj = nil
klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k)
} else if !exists {
deletedObj = nil
klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k)
}
queuedDeletions++
if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil {
return err
}
}
}
这只是cache包的一角,但也能看出,DeletedFinalStateUnknown是一个缓存已被删除对象的一种机制,如果需要,记得使用它。