Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --What happened: In reviewing another PR, I noticed incorrect commentary and code. The primary offense is at , where a comment asserts (incorrectly) that a key can be present in but not and the code removes a key from without ensuring it is absent from . The only saving grace is that this code is actually unreachable (as also noted in the comment). I think it would be better to fix the comment and in this unreachable situation, than to violate an invariant that is critical to other code in this file. also contemplates the possibility that a key can be in and absent from . What you expected to happen: I expected there to be no comments or code that contemplate violations of the invariant at How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): current branch Cloud provider or hardware configuration: OS (e.g: ): Kernel (e.g. ): Install tools: Network plugin and version (if this is a network-related bug): Others:
Sorry, I should have noticed this in my earlier pass over this code.
Agreed. Was discussing this with at
We discussed this one, Mike will send PR, Daniel will review.

Discussion:
// DeltaFIFO's Pop(), Get(), and GetByKey() methods return // interface{} to satisfy the Store/Queue interfaces, but they // will always return an object of type Deltas. List() returns <del> // the newest objects currently in the FIFO. </del> <ins> // the newest object from each accumulator in the FIFO. </ins> // // A DeltaFIFO's knownObjects KeyListerGetter provides the abilities // to list Store keys and to get objects by Store key.  The objects in

lock sync.RWMutex cond sync.Cond <del> // `items` maps keys to Deltas. // `queue` maintains FIFO order of keys for consumption in Pop(). // We maintain the property that keys in the `items` and `queue` are // strictly 1:1 mapping, and that all Deltas in `items` should have // at least one Delta. </del> <ins> // `items` maps a key to a Deltas. // Each such Deltas has at least one Delta. </ins> items map[string]Deltas <ins> // `queue` maintains FIFO order of keys for consumption in Pop(). // There are no duplicates in `queue`. // A key is in `queue` if and only if it is in `items`. </ins> queue []string // populated is true if the first batch of items inserted by Replace() has been populated

if err != nil { return KeyError{obj, err} } <del> newDeltas := append(f.items[id], Delta{actionType, obj}) </del> <ins> oldDeltas := f.items[id] newDeltas := append(oldDeltas, Delta{actionType, obj}) </ins> newDeltas = dedupDeltas(newDeltas) if len(newDeltas) > 0 {

} else { // This never happens, because dedupDeltas never returns an empty list // when given a non-empty list (as it is here). <del> // But if somehow it ever does return an empty list, then // We need to remove this from our map (extra items in the queue are // ignored if they are not in the map). delete(f.items, id) </del> <ins> // If somehow it happens anyway, deal with it but complain. if oldDeltas == nil { klog.Errorf("Impossible dedupDeltas for id=%q: oldDeltas=%#+v, obj=%#+v; ignoring", id, oldDeltas, obj) return nil } klog.Errorf("Impossible dedupDeltas for id=%q: oldDeltas=%#+v, obj=%#+v; breaking invariant by storing empty Deltas", id, oldDeltas, obj) f.items[id] = newDeltas return fmt.Errorf("Impossible dedupDeltas for id=%q: oldDeltas=%#+v, obj=%#+v; broke DeltaFIFO invariant by storing empty Deltas", id, oldDeltas, obj) </ins> } return nil }

return f.closed } <del> // Pop blocks until an item is added to the queue, and then returns it.  If </del> <ins> // Pop blocks until the queue has some items, and then returns one.  If </ins> // multiple items are ready, they are returned in the order in which they were // added/updated. The item is removed from the queue (and the store) before it // is returned, so if you don't successfully process it, you need to add it back

} item, ok := f.items[id] if !ok { <del> // Item may have been deleted subsequently. </del> <ins> // This should never happen klog.Errorf("Inconceivable! %q was in f.queue but not f.items; ignoring.", id) </ins> continue } delete(f.items, id)