diff --git a/tools/cache/delta_fifo.go b/tools/cache/delta_fifo.go index 1db3a01b..55ecdcdf 100644 --- a/tools/cache/delta_fifo.go +++ b/tools/cache/delta_fifo.go @@ -295,13 +295,6 @@ func isDeletionDup(a, b *Delta) *Delta { return b } -// willObjectBeDeletedLocked returns true only if the last delta for the -// given object is Delete. Caller must lock first. -func (f *DeltaFIFO) willObjectBeDeletedLocked(id string) bool { - deltas := f.items[id] - return len(deltas) > 0 && deltas[len(deltas)-1].Type == Deleted -} - // queueActionLocked appends to the delta list for the object. // Caller must lock first. func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) error { @@ -310,13 +303,6 @@ func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) err return KeyError{obj, err} } - // If object is supposed to be deleted (last event is Deleted), - // then we should ignore Sync events, because it would result in - // recreation of this object. - if actionType == Sync && f.willObjectBeDeletedLocked(id) { - return nil - } - newDeltas := append(f.items[id], Delta{actionType, obj}) newDeltas = dedupDeltas(newDeltas) diff --git a/tools/cache/delta_fifo_test.go b/tools/cache/delta_fifo_test.go index afe0a5a4..fc8235b4 100644 --- a/tools/cache/delta_fifo_test.go +++ b/tools/cache/delta_fifo_test.go @@ -85,6 +85,33 @@ func TestDeltaFIFO_basic(t *testing.T) { } } +// TestDeltaFIFO_replaceWithDeleteDeltaIn tests that a `Sync` delta for an +// object `O` with ID `X` is added when .Replace is called and `O` is among the +// replacement objects even if the DeltaFIFO already stores in terminal position +// a delta of type `Delete` for ID `X`. Not adding the `Sync` delta causes +// SharedIndexInformers to miss `O`'s create notification, see https://github.com/kubernetes/kubernetes/issues/83810 +// for more details. +func TestDeltaFIFO_replaceWithDeleteDeltaIn(t *testing.T) { + oldObj := mkFifoObj("foo", 1) + newObj := mkFifoObj("foo", 2) + + f := NewDeltaFIFO(testFifoObjectKeyFunc, keyLookupFunc(func() []testFifoObject { + return []testFifoObject{oldObj} + })) + + f.Delete(oldObj) + f.Replace([]interface{}{newObj}, "") + + actualDeltas := Pop(f) + expectedDeltas := Deltas{ + Delta{Type: Deleted, Object: oldObj}, + Delta{Type: Sync, Object: newObj}, + } + if !reflect.DeepEqual(expectedDeltas, actualDeltas) { + t.Errorf("expected %#v, got %#v", expectedDeltas, actualDeltas) + } +} + func TestDeltaFIFO_requeueOnPop(t *testing.T) { f := NewDeltaFIFO(testFifoObjectKeyFunc, nil)