The main advantage is that waiting on channels creates a causal relationship
between goroutines which is visible to synctest. When a controller in a
synctest bubble does a WaitFor in a test's background goroutine for the
controller, the test can use synctest.Wait to wait for completion of cache
sync, without requiring any test specific "has controller synced" API. Without
this, the test had to poll or otherwise wait for the controller.
The polling in WaitForCacheSync moved the virtual clock forward by a random
amount, depending on how often it had to check in wait.Poll. Now tests can be
written such that all events during a test happen at a predictable time. This
will be demonstrated in a separate commit for the
pkg/controller/devicetainteviction unit test.
The benefit for normal production is immediate continuation when the last
informer is synced (not really a problem, but still...) and more important,
nicer logging thanks to the names associated with the thing that is being
waited for. The caller decides whether logging is enabled or disabled and
describes what is being waited for (typically informer caches, but maybe also
event handlers or even something else entirely as long as it implements the
DoneChecker interface).
Before:
Waiting for caches to sync
Caches are synced
After:
Waiting for="cache and event handler sync"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.Pod"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceClaim"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceSlice"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.DeviceClass"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1alpha3.DeviceTaintRule"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceClaim + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.Pod + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1alpha3.DeviceTaintRule + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
Done waiting for="cache and event handler sync" instance="SharedIndexInformer *v1.ResourceSlice + event handler k8s.io/kubernetes/pkg/controller/devicetainteviction.(*Controller).Run"
The "SharedIndexInformer *v1.Pod" is also how this appears in metrics.
Kubernetes-commit: fdcbb6cba9a04c028b158bf66d505df7431f63fe
Signed-off-by: Min Jin <minkimzz@amazon.com>
Update staging/src/k8s.io/client-go/tools/cache/the_real_fifo.go
optimizing fifo loop
Co-authored-by: Marek Siarkowicz <marek.siarkowicz@protonmail.com>
Signed-off-by: Min Jin <minkimzz@amazon.com>
refactoring PopBatch to accept []Delta
Signed-off-by: Min Jin <minkimzz@amazon.com>
Kubernetes-commit: 611b4c1408f529de4d4e94e6dd33be2ed1df9276
updating to include initialization in func
Update store to use sets.Set
updating tests to use sets.New instead of sets.NewString
update store_test
update index_test
update controller_test file
update delta_fifo file
update expiration_cache_fakes file
update index_test file
update thread_safe_store file
update events_cache file
update thread_safe_store_test
update expiration_cache_test
small refactor of for loop
unexport the Index type -> index
Kubernetes-commit: c08b9ab3b5c78023e46ce03fde894b24533c68ef
The Lister and Watcher interfaces only supported methods without context, but
were typically implemented with client-go API calls which need a context. New
interfaces get added using the same approach as in
https://github.com/kubernetes/kubernetes/pull/129109.
Kubernetes-commit: 6688adae142e37114d9dfa8d94cd1d8a91fbcc13
Logically a cache.Queue.AddIfNotPresent means that the informer can move
back in time since an older item is placed after newer items. The
alternative of placing errors at the head of the queue leads to
indefinite memory growth and repeated failures on retry.
Luckily this behavior was behind RetryOnError, which was always set to
false and impossible for normal users to set to true. By removing the
function and setting, impacted users (none found in a github search)
will get a compile failure.
Kubernetes-commit: 8e77ac000131019d5aa49c19aa1f477f6dac4d59
The test relied on a 100ms sleep to ensure that controller was done. If that
race was lost, one goroutine was intentionally prevented from completing by
locking a mutex permanently. A TODO was left about detecting that.
Adding goroutine leak checking in
https://github.com/kubernetes/kubernetes/pull/126387 revealed that this race
indeed sometimes is lost because the goroutine
leaked (https://github.com/kubernetes/kubernetes/issues/129400).
Waiting for controller shutdown instead of relying on timing should fix this.
Kubernetes-commit: 8e1403563a60f3b7a258e3bbb64b5c3a7f6548fb
The context is used for cancellation and to support contextual logging.
In most cases, alternative *WithContext APIs get added, except for
NewIntegerResourceVersionMutationCache where code searches indicate that the
API is not used downstream.
An API break around SharedInformer couldn't be avoided because the
alternative (keeping the interface unchanged and adding a second one with
the new method) would have been worse. controller-runtime needs to be updated
because it implements that interface in a test package. Downstream consumers of
controller-runtime will work unless they use those test package.
Converting Kubernetes to use the other new alternatives will follow. In the
meantime, usage of the new alternatives cannot be enforced via logcheck
yet (see https://github.com/kubernetes/kubernetes/issues/126379 for the
process).
Passing context through and checking it for cancellation is tricky for event
handlers. A better approach is to map the context cancellation to the normal
removal of an event handler via a helper goroutine. Thanks to the new
HandleErrorWithLogr and HandleCrashWithLogr, remembering the logger is
sufficient for handling problems at runtime.
Kubernetes-commit: 4638ba971661497b147906b8977ae206c9dd6e44
Several tests leaked goroutines. All of those get fixed where possible
without API changes. Goleak is used to prevent regressions.
One new test specifically covers shutdown of an informer and its event
handlers.
Kubernetes-commit: 0ba43734b4c8998b4aaeb1fa2bec8dee609fa50a
* Add tracker types and tests
* Modify ResourceEventHandler interface's OnAdd member
* Add additional ResourceEventHandlerDetailedFuncs struct
* Fix SharedInformer to let users track HasSynced for their handlers
* Fix in-tree controllers which weren't computing HasSynced correctly
* Deprecate the cache.Pop function
Kubernetes-commit: 8100efc7b3122ad119ee8fa4bbbedef3b90f2e0d
TransformingInfomer is like a regular Informer, but allows for applying
custom transform functions on the objects received via list/watch API calls.
Kubernetes-commit: efd3490076c391823095b4c8bd6e847ae18eb012
Nobody uses it; the one or two older users from 1.4/1.5 timeframe
were removed for 1.6. It's also poorly understood and the sole
example is in the testcases, and it's pretty incomplete.
If anyone really wants compression, they can revert this PR.
Kubernetes-commit: a56c8f50cb9b9bfdb92bc5f005a48f8df5afadb9