From 56cda35ac9ce9a17572022b74904d7676faa833e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Wed, 21 May 2025 16:54:02 +0200 Subject: [PATCH 1/6] fix: primary cache utils mechanism MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../PrimaryUpdateAndCacheUtils.java | 55 ++++++++++++++---- .../informer/TemporaryResourceCache.java | 4 +- .../PrimaryUpdateAndCacheUtilsTest.java | 57 ++++++++++++++++++- ...va => StatusPatchCacheCustomResource.java} | 5 +- ...ithLockIT.java => StatusPatchCacheIT.java} | 12 ++-- ...r.java => StatusPatchCacheReconciler.java} | 20 +++---- ...ockSpec.java => StatusPatchCacheSpec.java} | 2 +- ...tatus.java => StatusPatchCacheStatus.java} | 4 +- 8 files changed, 119 insertions(+), 40 deletions(-) rename operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/{StatusPatchCacheWithLockCustomResource.java => StatusPatchCacheCustomResource.java} (69%) rename operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/{StatusPatchCacheWithLockIT.java => StatusPatchCacheIT.java} (79%) rename operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/{StatusPatchCacheWithLockReconciler.java => StatusPatchCacheReconciler.java} (73%) rename operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/{StatusPatchCacheWithLockSpec.java => StatusPatchCacheSpec.java} (82%) rename operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/{StatusPatchCacheWithLockStatus.java => StatusPatchCacheStatus.java} (62%) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index ac0fe9675c..9b41bf33e3 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.api.reconciler; +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; import java.util.function.UnaryOperator; import org.slf4j.Logger; @@ -25,6 +27,8 @@ public class PrimaryUpdateAndCacheUtils { public static final int DEFAULT_MAX_RETRY = 10; + public static final int RESOURCE_CACHE_POLL_TIMEOUT = 10000; + public static final int DEFAULT_SLEEP_FOR_CACHE_POLL_MILLIS = 30; private PrimaryUpdateAndCacheUtils() {} @@ -90,8 +94,8 @@ public static

P ssaPatchStatusAndCacheResource( } /** - * Same as {@link #updateAndCacheResource(HasMetadata, Context, UnaryOperator, UnaryOperator, - * int)} using the default maximum retry number as defined by {@link #DEFAULT_MAX_RETRY}. + * Same as {@link #updateAndCacheResource(HasMetadata, Context, UnaryOperator, UnaryOperator, int, + * long,long)} using the default maximum retry number as defined by {@link #DEFAULT_MAX_RETRY}. * * @param resourceToUpdate original resource to update * @param context of reconciliation @@ -106,7 +110,13 @@ public static

P updateAndCacheResource( UnaryOperator

modificationFunction, UnaryOperator

updateMethod) { return updateAndCacheResource( - resourceToUpdate, context, modificationFunction, updateMethod, DEFAULT_MAX_RETRY); + resourceToUpdate, + context, + modificationFunction, + updateMethod, + DEFAULT_MAX_RETRY, + RESOURCE_CACHE_POLL_TIMEOUT, + DEFAULT_SLEEP_FOR_CACHE_POLL_MILLIS); } /** @@ -133,7 +143,9 @@ public static

P updateAndCacheResource( Context

context, UnaryOperator

modificationFunction, UnaryOperator

updateMethod, - int maxRetry) { + int maxRetry, + long cachePollTimeoutMillis, + long pollDelayMillis) { if (log.isDebugEnabled()) { log.debug("Conflict retrying update for: {}", ResourceID.fromResource(resourceToUpdate)); @@ -180,14 +192,35 @@ public static

P updateAndCacheResource( resourceToUpdate.getMetadata().getNamespace(), e.getCode()); resourceToUpdate = - (P) - context - .getClient() - .resources(resourceToUpdate.getClass()) - .inNamespace(resourceToUpdate.getMetadata().getNamespace()) - .withName(resourceToUpdate.getMetadata().getName()) - .get(); + pollLocalCache(context, resourceToUpdate, cachePollTimeoutMillis, pollDelayMillis); + } + } + } + + private static

P pollLocalCache( + Context

context, P staleResource, long timeoutMillis, long pollDelayMillis) { + try { + var resourceId = ResourceID.fromResource(staleResource); + var startTime = LocalTime.now(); + while (startTime.plus(timeoutMillis, ChronoUnit.MILLIS).isAfter(LocalTime.now())) { + log.debug("Polling cache for resource: {}", resourceId); + var cachedResource = context.getPrimaryCache().get(resourceId).orElseThrow(); + if (!cachedResource + .getMetadata() + .getResourceVersion() + .equals(staleResource.getMetadata().getResourceVersion())) { + return context + .getControllerConfiguration() + .getConfigurationService() + .getResourceCloner() + .clone(cachedResource); + } + Thread.sleep(pollDelayMillis); } + throw new OperatorException("Timeout of resource polling from cache for resource"); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new OperatorException(e); } } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/TemporaryResourceCache.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/TemporaryResourceCache.java index 9ec5b3694c..af75a5abc4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/TemporaryResourceCache.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/TemporaryResourceCache.java @@ -126,9 +126,7 @@ public synchronized void putResource(T newResource, String previousResourceVersi knownResourceVersions.add(newResource.getMetadata().getResourceVersion()); } var resourceId = ResourceID.fromResource(newResource); - var cachedResource = - getResourceFromCache(resourceId) - .orElse(managedInformerEventSource.get(resourceId).orElse(null)); + var cachedResource = managedInformerEventSource.get(resourceId).orElse(null); boolean moveAhead = false; if (previousResourceVersion == null && cachedResource == null) { diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtilsTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtilsTest.java index 438941db9c..80a254b50f 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtilsTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtilsTest.java @@ -1,16 +1,22 @@ package io.javaoperatorsdk.operator.api.reconciler; +import java.util.Optional; import java.util.function.UnaryOperator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.utils.KubernetesSerialization; import io.javaoperatorsdk.operator.OperatorException; import io.javaoperatorsdk.operator.TestUtils; +import io.javaoperatorsdk.operator.api.config.Cloner; +import io.javaoperatorsdk.operator.api.config.ConfigurationService; +import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.processing.event.EventSourceRetriever; import io.javaoperatorsdk.operator.processing.event.source.controller.ControllerEventSource; import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; @@ -29,6 +35,7 @@ class PrimaryUpdateAndCacheUtilsTest { Context context = mock(Context.class); KubernetesClient client = mock(KubernetesClient.class); Resource resource = mock(Resource.class); + IndexedResourceCache primaryCache = mock(IndexedResourceCache.class); @BeforeEach void setup() { @@ -41,6 +48,20 @@ void setup() { when(mixedOp.inNamespace(any())).thenReturn(mixedOp); when(mixedOp.withName(any())).thenReturn(resource); when(resource.get()).thenReturn(TestUtils.testCustomResource1()); + when(context.getPrimaryCache()).thenReturn(primaryCache); + + var controllerConfiguration = mock(ControllerConfiguration.class); + when(context.getControllerConfiguration()).thenReturn(controllerConfiguration); + var configService = mock(ConfigurationService.class); + when(controllerConfiguration.getConfigurationService()).thenReturn(configService); + when(configService.getResourceCloner()) + .thenReturn( + new Cloner() { + @Override + public R clone(R object) { + return new KubernetesSerialization().clone(object); + } + }); } @Test @@ -76,6 +97,10 @@ void retriesConflicts() { when(updateOperation.apply(any())) .thenThrow(new KubernetesClientException("", 409, null)) .thenReturn(TestUtils.testCustomResource1()); + var freshResource = TestUtils.testCustomResource1(); + + freshResource.getMetadata().setResourceVersion("2"); + when(primaryCache.get(any())).thenReturn(Optional.of(freshResource)); var updated = PrimaryUpdateAndCacheUtils.updateAndCacheResource( @@ -89,7 +114,7 @@ void retriesConflicts() { updateOperation); assertThat(updated).isNotNull(); - verify(resource, times(1)).get(); + verify(primaryCache, times(1)).get(any()); } @Test @@ -97,7 +122,13 @@ void throwsIfRetryExhausted() { var updateOperation = mock(UnaryOperator.class); when(updateOperation.apply(any())).thenThrow(new KubernetesClientException("", 409, null)); + var stubbing = when(primaryCache.get(any())); + for (int i = 0; i < DEFAULT_MAX_RETRY; i++) { + var resource = TestUtils.testCustomResource1(); + resource.getMetadata().setResourceVersion("" + i); + stubbing = stubbing.thenReturn(Optional.of(resource)); + } assertThrows( OperatorException.class, () -> @@ -106,6 +137,28 @@ void throwsIfRetryExhausted() { context, UnaryOperator.identity(), updateOperation)); - verify(resource, times(DEFAULT_MAX_RETRY)).get(); + verify(primaryCache, times(DEFAULT_MAX_RETRY)).get(any()); + } + + @Test + void cachePollTimeouts() { + var updateOperation = mock(UnaryOperator.class); + + when(updateOperation.apply(any())).thenThrow(new KubernetesClientException("", 409, null)); + when(primaryCache.get(any())).thenReturn(Optional.of(TestUtils.testCustomResource1())); + + var ex = + assertThrows( + OperatorException.class, + () -> + PrimaryUpdateAndCacheUtils.updateAndCacheResource( + TestUtils.testCustomResource1(), + context, + UnaryOperator.identity(), + updateOperation, + 2, + 50L, + 10L)); + assertThat(ex.getMessage()).contains("Timeout"); } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheCustomResource.java similarity index 69% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockCustomResource.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheCustomResource.java index 8ab742a975..e87d8e8714 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheCustomResource.java @@ -9,6 +9,5 @@ @Group("sample.javaoperatorsdk") @Version("v1") @ShortNames("spwl") -public class StatusPatchCacheWithLockCustomResource - extends CustomResource - implements Namespaced {} +public class StatusPatchCacheCustomResource + extends CustomResource implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheIT.java similarity index 79% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockIT.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheIT.java index c5752f4aae..9d0b923056 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheIT.java @@ -11,19 +11,19 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -public class StatusPatchCacheWithLockIT { +public class StatusPatchCacheIT { public static final String TEST_1 = "test1"; @RegisterExtension LocallyRunOperatorExtension extension = LocallyRunOperatorExtension.builder() - .withReconciler(StatusPatchCacheWithLockReconciler.class) + .withReconciler(StatusPatchCacheReconciler.class) .build(); @Test void testStatusAlwaysUpToDate() { - var reconciler = extension.getReconcilerOfType(StatusPatchCacheWithLockReconciler.class); + var reconciler = extension.getReconcilerOfType(StatusPatchCacheReconciler.class); extension.create(testResource()); @@ -39,10 +39,10 @@ void testStatusAlwaysUpToDate() { }); } - StatusPatchCacheWithLockCustomResource testResource() { - var res = new StatusPatchCacheWithLockCustomResource(); + StatusPatchCacheCustomResource testResource() { + var res = new StatusPatchCacheCustomResource(); res.setMetadata(new ObjectMetaBuilder().withName(TEST_1).build()); - res.setSpec(new StatusPatchCacheWithLockSpec()); + res.setSpec(new StatusPatchCacheSpec()); return res; } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockReconciler.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheReconciler.java similarity index 73% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockReconciler.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheReconciler.java index 364f8e9ff5..69215d6d01 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockReconciler.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheReconciler.java @@ -12,16 +12,14 @@ import io.javaoperatorsdk.operator.processing.event.source.EventSource; @ControllerConfiguration -public class StatusPatchCacheWithLockReconciler - implements Reconciler { +public class StatusPatchCacheReconciler implements Reconciler { public volatile int latestValue = 0; public volatile boolean errorPresent = false; @Override - public UpdateControl reconcile( - StatusPatchCacheWithLockCustomResource resource, - Context context) { + public UpdateControl reconcile( + StatusPatchCacheCustomResource resource, Context context) { if (resource.getStatus() != null && resource.getStatus().getValue() != latestValue) { errorPresent = true; @@ -50,22 +48,20 @@ public UpdateControl reconcile( } @Override - public List> prepareEventSources( - EventSourceContext context) { + public List> prepareEventSources( + EventSourceContext context) { // periodic event triggering for testing purposes return List.of(new PeriodicTriggerEventSource<>(context.getPrimaryCache())); } - private StatusPatchCacheWithLockCustomResource createFreshCopy( - StatusPatchCacheWithLockCustomResource resource) { - var res = new StatusPatchCacheWithLockCustomResource(); + private StatusPatchCacheCustomResource createFreshCopy(StatusPatchCacheCustomResource resource) { + var res = new StatusPatchCacheCustomResource(); res.setMetadata( new ObjectMetaBuilder() .withName(resource.getMetadata().getName()) .withNamespace(resource.getMetadata().getNamespace()) .build()); - res.setStatus(new StatusPatchCacheWithLockStatus()); - + res.setStatus(new StatusPatchCacheStatus()); return res; } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockSpec.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheSpec.java similarity index 82% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockSpec.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheSpec.java index ebbabd49a0..0885b6a858 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockSpec.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheSpec.java @@ -1,6 +1,6 @@ package io.javaoperatorsdk.operator.baseapi.statuscache; -public class StatusPatchCacheWithLockSpec { +public class StatusPatchCacheSpec { private int counter = 0; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockStatus.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheStatus.java similarity index 62% rename from operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockStatus.java rename to operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheStatus.java index 5f2d8f5a6f..5918b2e3b8 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheWithLockStatus.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/statuscache/StatusPatchCacheStatus.java @@ -1,6 +1,6 @@ package io.javaoperatorsdk.operator.baseapi.statuscache; -public class StatusPatchCacheWithLockStatus { +public class StatusPatchCacheStatus { private Integer value = 0; @@ -8,7 +8,7 @@ public Integer getValue() { return value; } - public StatusPatchCacheWithLockStatus setValue(Integer value) { + public StatusPatchCacheStatus setValue(Integer value) { this.value = value; return this; } From f6b2777d352131edc2f89a2b1af13a4851cb65e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Thu, 22 May 2025 09:32:30 +0200 Subject: [PATCH 2/6] increase default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../operator/api/reconciler/PrimaryUpdateAndCacheUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index 9b41bf33e3..01247d9840 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -28,7 +28,7 @@ public class PrimaryUpdateAndCacheUtils { public static final int DEFAULT_MAX_RETRY = 10; public static final int RESOURCE_CACHE_POLL_TIMEOUT = 10000; - public static final int DEFAULT_SLEEP_FOR_CACHE_POLL_MILLIS = 30; + public static final int DEFAULT_SLEEP_FOR_CACHE_POLL_MILLIS = 50; private PrimaryUpdateAndCacheUtils() {} From d3e7e47b4e747d3c6918cb525e8d7cd4d8ae7ec5 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 23 May 2025 09:40:15 +0200 Subject: [PATCH 3/6] docs: add javadoc parameter descriptions Signed-off-by: Chris Laprun --- .../operator/api/reconciler/PrimaryUpdateAndCacheUtils.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index 01247d9840..abc2651761 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -134,6 +134,8 @@ public static

P updateAndCacheResource( * @param modificationFunction modifications to make on primary * @param updateMethod the update method implementation * @param maxRetry maximum number of retries before giving up + * @param cachePollTimeoutMillis maximum amount of milliseconds to wait for the updated resource to appear in cache + * @param cachePollPeriodMillis cache polling period, in milliseconds * @param

primary type * @return the updated resource */ @@ -145,7 +147,7 @@ public static

P updateAndCacheResource( UnaryOperator

updateMethod, int maxRetry, long cachePollTimeoutMillis, - long pollDelayMillis) { + long cachePollPeriodMillis) { if (log.isDebugEnabled()) { log.debug("Conflict retrying update for: {}", ResourceID.fromResource(resourceToUpdate)); @@ -192,7 +194,7 @@ public static

P updateAndCacheResource( resourceToUpdate.getMetadata().getNamespace(), e.getCode()); resourceToUpdate = - pollLocalCache(context, resourceToUpdate, cachePollTimeoutMillis, pollDelayMillis); + pollLocalCache(context, resourceToUpdate, cachePollTimeoutMillis, cachePollPeriodMillis); } } } From 0f66ee6d141b799e2255921cc46c80598688a330 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 23 May 2025 09:40:39 +0200 Subject: [PATCH 4/6] refactor: avoid recomputing timeout time each iteration Signed-off-by: Chris Laprun --- .../operator/api/reconciler/PrimaryUpdateAndCacheUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index abc2651761..b8bfff2fe6 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -204,7 +204,8 @@ private static

P pollLocalCache( try { var resourceId = ResourceID.fromResource(staleResource); var startTime = LocalTime.now(); - while (startTime.plus(timeoutMillis, ChronoUnit.MILLIS).isAfter(LocalTime.now())) { + final var timeoutTime = startTime.plus(timeoutMillis, ChronoUnit.MILLIS); + while (timeoutTime.isAfter(LocalTime.now())) { log.debug("Polling cache for resource: {}", resourceId); var cachedResource = context.getPrimaryCache().get(resourceId).orElseThrow(); if (!cachedResource From dc387519fe06fd3242c343855d330d10578afb33 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 23 May 2025 09:48:39 +0200 Subject: [PATCH 5/6] refactor: better constant names Signed-off-by: Chris Laprun --- .../reconciler/PrimaryUpdateAndCacheUtils.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index b8bfff2fe6..8b1d53cf33 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -27,8 +27,8 @@ public class PrimaryUpdateAndCacheUtils { public static final int DEFAULT_MAX_RETRY = 10; - public static final int RESOURCE_CACHE_POLL_TIMEOUT = 10000; - public static final int DEFAULT_SLEEP_FOR_CACHE_POLL_MILLIS = 50; + public static final int DEFAULT_RESOURCE_CACHE_TIMEOUT_MILLIS = 10000; + public static final int DEFAULT_RESOURCE_CACHE_POLL_PERIOD_MILLIS = 50; private PrimaryUpdateAndCacheUtils() {} @@ -115,8 +115,8 @@ public static

P updateAndCacheResource( modificationFunction, updateMethod, DEFAULT_MAX_RETRY, - RESOURCE_CACHE_POLL_TIMEOUT, - DEFAULT_SLEEP_FOR_CACHE_POLL_MILLIS); + DEFAULT_RESOURCE_CACHE_TIMEOUT_MILLIS, + DEFAULT_RESOURCE_CACHE_POLL_PERIOD_MILLIS); } /** @@ -134,12 +134,12 @@ public static

P updateAndCacheResource( * @param modificationFunction modifications to make on primary * @param updateMethod the update method implementation * @param maxRetry maximum number of retries before giving up - * @param cachePollTimeoutMillis maximum amount of milliseconds to wait for the updated resource to appear in cache + * @param cachePollTimeoutMillis maximum amount of milliseconds to wait for the updated resource + * to appear in cache * @param cachePollPeriodMillis cache polling period, in milliseconds * @param

primary type * @return the updated resource */ - @SuppressWarnings("unchecked") public static

P updateAndCacheResource( P resourceToUpdate, Context

context, @@ -194,7 +194,8 @@ public static

P updateAndCacheResource( resourceToUpdate.getMetadata().getNamespace(), e.getCode()); resourceToUpdate = - pollLocalCache(context, resourceToUpdate, cachePollTimeoutMillis, cachePollPeriodMillis); + pollLocalCache( + context, resourceToUpdate, cachePollTimeoutMillis, cachePollPeriodMillis); } } } From 0f302bf72f0a21e93af99556528767dc226579f9 Mon Sep 17 00:00:00 2001 From: Chris Laprun Date: Fri, 23 May 2025 09:48:59 +0200 Subject: [PATCH 6/6] docs: add mention of defaults in javadoc Signed-off-by: Chris Laprun --- .../operator/api/reconciler/PrimaryUpdateAndCacheUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java index 8b1d53cf33..c61cc837c1 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java @@ -95,7 +95,9 @@ public static

P ssaPatchStatusAndCacheResource( /** * Same as {@link #updateAndCacheResource(HasMetadata, Context, UnaryOperator, UnaryOperator, int, - * long,long)} using the default maximum retry number as defined by {@link #DEFAULT_MAX_RETRY}. + * long,long)} using the default maximum retry number as defined by {@link #DEFAULT_MAX_RETRY} and + * default cache maximum polling time and period as defined, respectively by {@link + * #DEFAULT_RESOURCE_CACHE_TIMEOUT_MILLIS} and {@link #DEFAULT_RESOURCE_CACHE_POLL_PERIOD_MILLIS}. * * @param resourceToUpdate original resource to update * @param context of reconciliation