-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Describe the bug
In our service, we utilize the SharedInformerFactory to generate informers. However, we encountered unexpected behavior when invoking it multiple times. Specifically, it returns a new informer for the same apiTypeClass without maintaining it within the internal map named informers. Consequently, when we call the io.kubernetes.client.informer.SharedInformerFactory#startAllRegisteredInformers method, our informer doesn't start as anticipated. The code is as follows:
public synchronized <ApiType extends KubernetesObject, ApiListType extends KubernetesListObject>
SharedIndexInformer<ApiType> sharedIndexInformerFor(
ListerWatcher<ApiType, ApiListType> listerWatcher,
Class<ApiType> apiTypeClass,
long resyncPeriodInMillis,
BiConsumer<Class<ApiType>, Throwable> exceptionHandler) {
SharedIndexInformer<ApiType> informer =
new DefaultSharedIndexInformer<>(
apiTypeClass, listerWatcher, resyncPeriodInMillis, new Cache<>(), exceptionHandler);
this.informers.putIfAbsent(TypeToken.get(apiTypeClass).getType(), informer);
return informer;
}This is a bit confusing. I don't understand why the factory created it but doesn't keep it. Could someone explain the purpose of this design to me?
Describe the solution you'd like
I believe the factory should retain all the informers it creates, ensuring that when we call startAllRegisteredInformers, the returned informer starts correctly. Alternatively, the method SharedInformerFactory#sharedIndexInformerFor should be idempotent. This means that if we create an informer for the same apiClassType, it should return the initial instance, similar to the behavior observed in the Go client.
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(obj)
informer, exists := f.informers[informerType]
if exists {
return informer
}
resyncPeriod, exists := f.customResync[informerType]
if !exists {
resyncPeriod = f.defaultResync
}
informer = newFunc(f.client, resyncPeriod)
informer.SetTransform(f.transform)
f.informers[informerType] = informer
return informer
}No response
Client Version
e.g. 8.0.2
Kubernetes Version
e.g. 1.19.3
Java Version
e.g. Java11