Description
What happened?
The functions SetWatchErrorHandler and SetTransform are racy with ShareInformer factory
Consider the following example:
informerFactory := informers.NewSharedInformerFactory(client, 0*time.Second)
go func() {
informerFactory.Start(stop)
}()
serviceInformer := informerFactory.Core().V1().Services().Informer()
serviceInformer.SetWatchErrorHandler(func(r *cache.Reflector, err error) {
// ...
})
In the real world, the goroutine running Start is likely entirely decoupled from the rest; the code here is fairly obviously "wrong".
This has both a data race (I have a PR ready for this) and a logical race. There is no safe way to call these functions unless the entire application is sequenced in a manner such that all informers are created before Start is called. In our real world case, we have some informers that start after application start, which leads to races with other components calling Start().
What did you expect to happen?
SetWatchErrorHandler and SetTransform can be called without races. That is, I can make an informer from a shared informer factory, set a watcher handler and transform, and ensure they are applied.
How can we reproduce it (as minimally and precisely as possible)?
See incoming PR which has a test case
Anything else we need to know?
No response
Kubernetes version
$ kubectl version
# paste output here
Cloud provider
OS version
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here
# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here