2727import io .kubernetes .client .util .Watchable ;
2828import io .kubernetes .client .util .generic .GenericKubernetesApi ;
2929import io .kubernetes .client .util .generic .options .ListOptions ;
30+ import okhttp3 .Call ;
31+ import org .apache .commons .collections4 .MapUtils ;
32+
3033import java .lang .reflect .Type ;
3134import java .util .HashMap ;
3235import java .util .Map ;
3336import java .util .concurrent .ExecutorService ;
3437import java .util .concurrent .Executors ;
3538import java .util .concurrent .Future ;
3639import java .util .function .BiConsumer ;
37- import okhttp3 .Call ;
38- import org .apache .commons .collections4 .MapUtils ;
3940
40- /** SharedInformerFactory class constructs and caches informers for api types. */
41+ /**
42+ * SharedInformerFactory class constructs and caches informers for api types.
43+ * For each api type, only the first created informer is stored in the cache.
44+ * If reuseExistingCachedInformer is set to true, It returns the cached informer when creating
45+ * an informer for the same api type.
46+ * Otherwise, this factory creates a new informer on each invocation.
47+ */
4148public class SharedInformerFactory {
4249
4350 protected Map <Type , SharedIndexInformer > informers ;
@@ -47,35 +54,54 @@ public class SharedInformerFactory {
4754 private ExecutorService informerExecutor ;
4855
4956 private ApiClient apiClient ;
57+ private boolean reuseExistingCachedInformer ;
5058
5159 /** Constructor w/ default thread pool. */
5260 /** DEPRECATE: In favor of explicit apiClient constructor to avoid misguiding */
5361 @ Deprecated
5462 public SharedInformerFactory () {
55- this (Configuration .getDefaultApiClient ().setReadTimeout (0 ), Executors .newCachedThreadPool ());
63+ this (Configuration .getDefaultApiClient ().setReadTimeout (0 ), Executors .newCachedThreadPool (), false );
5664 }
5765
58- /** Constructor w/ api client specified and default thread pool. */
66+ /**
67+ * Constructor w/ api client specified, default thread pool and reuseExistingCachedInformer is false.
68+ */
5969 public SharedInformerFactory (ApiClient apiClient ) {
60- this (apiClient , Executors .newCachedThreadPool ());
70+ this (apiClient , false );
71+ }
72+
73+ /**
74+ * Constructor w/ api client specified and default thread pool
75+ * @param apiClient specific api client
76+ * @param reuseCache Determines whether to utilize an existing cached informer.
77+ * If true, the method returns the first registered informer for multiple creations of the same apiClassType,
78+ * else, each method calls results in the creation of a new informer,
79+ * while only the first informer is stored in the cache.
80+ */
81+ public SharedInformerFactory (ApiClient apiClient , boolean reuseCache ) {
82+ this (apiClient , Executors .newCachedThreadPool (), reuseCache );
6183 }
6284
6385 /**
6486 * Constructor w/ thread pool specified.
65- *
66- * @param threadPool specified thread pool
87+ * DEPRECATE: In favor of explicit apiClient constructor to avoid misguiding.
6788 */
89+ @ Deprecated
6890 public SharedInformerFactory (ExecutorService threadPool ) {
69- this (Configuration .getDefaultApiClient ().setReadTimeout (0 ), threadPool );
91+ this (Configuration .getDefaultApiClient ().setReadTimeout (0 ),threadPool , false );
7092 }
7193
7294 /**
7395 * Constructor w/ api client and thread pool specified.
7496 *
7597 * @param client specific api client
7698 * @param threadPool specified thread pool
99+ * @param reuseCache Determines whether to utilize an existing cached informer.
100+ * If true, the method returns the first registered informer for multiple creations of the same apiClassType,
101+ * else, each method calls results in the creation of a new informer,
102+ * while only the first informer is stored in the cache.
77103 */
78- public SharedInformerFactory (ApiClient client , ExecutorService threadPool ) {
104+ public SharedInformerFactory (ApiClient client , ExecutorService threadPool , boolean reuseCache ) {
79105 if (client .getReadTimeout () != 0 ) {
80106 throw new IllegalArgumentException ("read timeout of ApiClient must be zero" );
81107 }
@@ -84,6 +110,7 @@ public SharedInformerFactory(ApiClient client, ExecutorService threadPool) {
84110 informerExecutor = threadPool ;
85111 informers = new HashMap <>();
86112 startedInformers = new HashMap <>();
113+ reuseExistingCachedInformer = reuseCache ;
87114 }
88115
89116 /**
@@ -105,8 +132,7 @@ SharedIndexInformer<ApiType> sharedIndexInformerFor(
105132 }
106133
107134 /**
108- * Constructs and returns a shared index informer w/ resync period specified. But the informer
109- * cache will not be overwritten i.e. only the first registered informer will be kept.
135+ * Constructs and returns a shared index informer w/ resync period specified.
110136 *
111137 * @param <ApiType> the type parameter
112138 * @param <ApiListType> the type parameter
@@ -151,9 +177,7 @@ SharedIndexInformer<ApiType> sharedIndexInformerFor(
151177 }
152178
153179 /**
154- * Constructs and returns a shared index informer by specifying lister-watcher. But the informer
155- * cache will not be overwritten on multiple call w/ the the same apiTypeClass i.e. only the first
156- * registered informer will be kept.
180+ * Constructs and returns a shared index informer by specifying lister-watcher.
157181 *
158182 * @param <ApiType> the type parameter
159183 * @param <ApiListType> the type parameter
@@ -176,18 +200,22 @@ SharedIndexInformer<ApiType> sharedIndexInformerFor(
176200 Class <ApiType > apiTypeClass ,
177201 long resyncPeriodInMillis ,
178202 BiConsumer <Class <ApiType >, Throwable > exceptionHandler ) {
203+ Type apiType = TypeToken .get (apiTypeClass ).getType ();
204+
205+ if (informers .containsKey (apiType ) && reuseExistingCachedInformer ) {
206+ return informers .get (apiType );
207+ }
179208
180209 SharedIndexInformer <ApiType > informer =
181210 new DefaultSharedIndexInformer <>(
182211 apiTypeClass , listerWatcher , resyncPeriodInMillis , new Cache <>(), exceptionHandler );
183- this .informers .putIfAbsent (TypeToken .get (apiTypeClass ).getType (), informer );
212+
213+ this .informers .putIfAbsent (apiType , informer );
184214 return informer ;
185215 }
186216
187217 /**
188- * Constructs and returns a shared index informer by specifying a generic api instance. But the
189- * informer cache will not be overwritten on multiple call w/ the the same apiTypeClass i.e. only
190- * the first registered informer will be kept.
218+ * Constructs and returns a shared index informer by specifying a generic api instance.
191219 *
192220 * @param <ApiType> the type parameter
193221 * @param <ApiListType> the type parameter
0 commit comments