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: While reviewing for I noticed that introduced a second type of Delta that is specific to DeltaFIFO but did not update the relevant documentation at , which was introduced by concurrent PR . What you expected to happen: I expected the documentation on DeltaFIFO to be current. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): 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:
BTW, I think it would be more reader-friendly if the definitions of Deltas and related types were closer to their mentions near the top of the file rather than near the end.
/help /triage accepted
This request has been marked as needing help from a contributor. Please ensure the request meets the requirements listed . If this request no longer meets these requirements, the label can be removed by commenting with the command. <detailsIn response to : /help /triage accepted </details
Hi, is someone working on this? If no, can I pick it up? Thanks.
: go ahead, and thanks!
Thanks! /assign

Discussion:
"k8s.io/klog/v2" ) <del> // NewDeltaFIFO returns a Queue which can be used to process changes to items. // // keyFunc is used to figure out what key an object should have. (It is // exposed in the returned DeltaFIFO's KeyOf() method, with additional handling // around deleted objects and queue state). // // 'knownObjects' may be supplied to modify the behavior of Delete, // Replace, and Resync.  It may be nil if you do not need those // modifications. // // TODO: consider merging keyLister with this object, tracking a list of //       "known" keys when Pop() is called. Have to think about how that //       affects error retrying. // NOTE: It is possible to misuse this and cause a race when using an //       external known object source. //       Whether there is a potential race depends on how the consumer //       modifies knownObjects. In Pop(), process function is called under //       lock, so it is safe to update data structures in it that need to be //       in sync with the queue (e.g. knownObjects). // //       Example: //       In case of sharedIndexInformer being a consumer //       (https://github.com/kubernetes/kubernetes/blob/0cdd940f/staging/ //       src/k8s.io/client-go/tools/cache/shared_informer.go#L192), //       there is no race as knownObjects (s.indexer) is modified safely //       under DeltaFIFO's lock. The only exceptions are GetStore() and //       GetIndexer() methods, which expose ways to modify the underlying //       storage. Currently these two methods are used for creating Lister //       and internal tests. // // Also see the comment on DeltaFIFO. // // Warning: This constructs a DeltaFIFO that does not differentiate between // events caused by a call to Replace (e.g., from a relist, which may // contain object updates), and synthetic events caused by a periodic resync // (which just emit the existing object). See https://issue.k8s.io/86015 for details. // // Use `NewDeltaFIFOWithOptions(DeltaFIFOOptions{..., EmitDeltaTypeReplaced: true})` // instead to receive a `Replaced` event depending on the type. // // Deprecated: Equivalent to NewDeltaFIFOWithOptions(DeltaFIFOOptions{KeyFunction: keyFunc, KnownObjects: knownObjects}) func NewDeltaFIFO(keyFunc KeyFunc, knownObjects KeyListerGetter) *DeltaFIFO { return NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KeyFunction:  keyFunc, KnownObjects: knownObjects, }) } </del> // DeltaFIFOOptions is the configuration parameters for DeltaFIFO. All are // optional. type DeltaFIFOOptions struct {

EmitDeltaTypeReplaced bool } <del> // NewDeltaFIFOWithOptions returns a Queue which can be used to process changes to // items. See also the comment on DeltaFIFO. func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { if opts.KeyFunction == nil { opts.KeyFunction = MetaNamespaceKeyFunc } f := &DeltaFIFO{ items:        map[string]Deltas{}, queue:        []string{}, keyFunc:      opts.KeyFunction, knownObjects: opts.KnownObjects, emitDeltaTypeReplaced: opts.EmitDeltaTypeReplaced, } f.cond.L = &f.lock return f } </del> // DeltaFIFO is like FIFO, but differs in two ways.  One is that the // accumulator associated with a given object's key is not that object // but rather a Deltas, which is a slice of Delta values for that

// Deleted if the older Deleted's object is a // DeletedFinalStateUnknown. // <del> // The other difference is that DeltaFIFO has an additional way that // an object can be applied to an accumulator, called Sync. </del> <ins> // The other difference is that DeltaFIFO has two additional ways that // an object can be applied to an accumulator: Replaced and Sync. // If EmitDeltaTypeReplaced is not set to true, Sync will be used in // replace events for backwards compatibility.  Sync is used for periodic // resync events. </ins> // // DeltaFIFO is a producer-consumer queue, where a Reflector is // intended to be the producer, and the consumer is whatever calls

emitDeltaTypeReplaced bool } <ins> // DeltaType is the type of a change (addition, deletion, etc) type DeltaType string // Change type definition const ( Added   DeltaType = "Added" Updated DeltaType = "Updated" Deleted DeltaType = "Deleted" // Replaced is emitted when we encountered watch errors and had to do a // relist. We don't know if the replaced object has changed. // // NOTE: Previous versions of DeltaFIFO would use Sync for Replace events // as well. Hence, Replaced is only emitted when the option // EmitDeltaTypeReplaced is true. Replaced DeltaType = "Replaced" // Sync is for synthetic events during a periodic resync. Sync DeltaType = "Sync" ) // Delta is a member of Deltas (a list of Delta objects) which // in its turn is the type stored by a DeltaFIFO. It tells you what // change happened, and the object's state after* that change. // // [*] Unless the change is a deletion, and then you'll get the final //     state of the object before it was deleted. type Delta struct { Type   DeltaType Object interface{} } // Deltas is a list of one or more 'Delta's to an individual object. // The oldest delta is at index 0, the newest delta is the last one. type Deltas []Delta // NewDeltaFIFO returns a Queue which can be used to process changes to items. // // keyFunc is used to figure out what key an object should have. (It is // exposed in the returned DeltaFIFO's KeyOf() method, with additional handling // around deleted objects and queue state). // // 'knownObjects' may be supplied to modify the behavior of Delete, // Replace, and Resync.  It may be nil if you do not need those // modifications. // // TODO: consider merging keyLister with this object, tracking a list of //       "known" keys when Pop() is called. Have to think about how that //       affects error retrying. // NOTE: It is possible to misuse this and cause a race when using an //       external known object source. //       Whether there is a potential race depends on how the consumer //       modifies knownObjects. In Pop(), process function is called under //       lock, so it is safe to update data structures in it that need to be //       in sync with the queue (e.g. knownObjects). // //       Example: //       In case of sharedIndexInformer being a consumer //       (https://github.com/kubernetes/kubernetes/blob/0cdd940f/staging/ //       src/k8s.io/client-go/tools/cache/shared_informer.go#L192), //       there is no race as knownObjects (s.indexer) is modified safely //       under DeltaFIFO's lock. The only exceptions are GetStore() and //       GetIndexer() methods, which expose ways to modify the underlying //       storage. Currently these two methods are used for creating Lister //       and internal tests. // // Also see the comment on DeltaFIFO. // // Warning: This constructs a DeltaFIFO that does not differentiate between // events caused by a call to Replace (e.g., from a relist, which may // contain object updates), and synthetic events caused by a periodic resync // (which just emit the existing object). See https://issue.k8s.io/86015 for details. // // Use `NewDeltaFIFOWithOptions(DeltaFIFOOptions{..., EmitDeltaTypeReplaced: true})` // instead to receive a `Replaced` event depending on the type. // // Deprecated: Equivalent to NewDeltaFIFOWithOptions(DeltaFIFOOptions{KeyFunction: keyFunc, KnownObjects: knownObjects}) func NewDeltaFIFO(keyFunc KeyFunc, knownObjects KeyListerGetter) *DeltaFIFO { return NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KeyFunction:  keyFunc, KnownObjects: knownObjects, }) } // NewDeltaFIFOWithOptions returns a Queue which can be used to process changes to // items. See also the comment on DeltaFIFO. func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { if opts.KeyFunction == nil { opts.KeyFunction = MetaNamespaceKeyFunc } f := &DeltaFIFO{ items:        map[string]Deltas{}, queue:        []string{}, keyFunc:      opts.KeyFunction, knownObjects: opts.KnownObjects, emitDeltaTypeReplaced: opts.EmitDeltaTypeReplaced, } f.cond.L = &f.lock return f } </ins> var ( _ = Queue(&DeltaFIFO{}) // DeltaFIFO is a Queue )

GetByKey(key string) (value interface{}, exists bool, err error) } <del> // DeltaType is the type of a change (addition, deletion, etc) type DeltaType string // Change type definition const ( Added   DeltaType = "Added" Updated DeltaType = "Updated" Deleted DeltaType = "Deleted" // Replaced is emitted when we encountered watch errors and had to do a // relist. We don't know if the replaced object has changed. // // NOTE: Previous versions of DeltaFIFO would use Sync for Replace events // as well. Hence, Replaced is only emitted when the option // EmitDeltaTypeReplaced is true. Replaced DeltaType = "Replaced" // Sync is for synthetic events during a periodic resync. Sync DeltaType = "Sync" ) // Delta is the type stored by a DeltaFIFO. It tells you what change // happened, and the object's state after* that change. // // [*] Unless the change is a deletion, and then you'll get the final //     state of the object before it was deleted. type Delta struct { Type   DeltaType Object interface{} } // Deltas is a list of one or more 'Delta's to an individual object. // The oldest delta is at index 0, the newest delta is the last one. type Deltas []Delta </del> // Oldest is a convenience function that returns the oldest delta, or // nil if there are no deltas. func (d Deltas) Oldest() *Delta {