From 8d0fb8e52e866311b39a2e47a0efd04e7a0360f5 Mon Sep 17 00:00:00 2001 From: csviri Date: Tue, 21 Mar 2023 16:31:00 +0100 Subject: [PATCH 1/8] feat: dynamic poll period for PerResourceEventSource --- .../PerResourcePollingEventSource.java | 111 +++++++++++++----- 1 file changed, 84 insertions(+), 27 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java index 8bf5c50fd4..11bb61583e 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java @@ -1,7 +1,8 @@ package io.javaoperatorsdk.operator.processing.event.source.polling; +import java.time.Duration; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.*; import java.util.function.Predicate; import org.slf4j.Logger; @@ -26,14 +27,17 @@ * @param the resource polled by the event source * @param

related custom resource */ +// todo check docs public class PerResourcePollingEventSource extends ExternalResourceCachingEventSource implements ResourceEventAware

{ private static final Logger log = LoggerFactory.getLogger(PerResourcePollingEventSource.class); - private final Timer timer = new Timer(); - private final Map timerTasks = new ConcurrentHashMap<>(); + public static final int DEFAULT_EXECUTOR_THREAD_NUMBER = 1; + + private final ScheduledExecutorService executorService; + private final Map> scheduledFutures = new ConcurrentHashMap<>(); private final ResourceFetcher resourceFetcher; private final Cache

resourceCache; private final Predicate

registerPredicate; @@ -57,11 +61,20 @@ public PerResourcePollingEventSource(ResourceFetcher resourceFetcher, Cache

resourceCache, long period, Predicate

registerPredicate, Class resourceClass, CacheKeyMapper cacheKeyMapper) { + this(resourceFetcher, resourceCache, period, registerPredicate, resourceClass, cacheKeyMapper, + new ScheduledThreadPoolExecutor(DEFAULT_EXECUTOR_THREAD_NUMBER)); + } + + public PerResourcePollingEventSource(ResourceFetcher resourceFetcher, + Cache

resourceCache, long period, + Predicate

registerPredicate, Class resourceClass, + CacheKeyMapper cacheKeyMapper, ScheduledExecutorService executorService) { super(resourceClass, cacheKeyMapper); this.resourceFetcher = resourceFetcher; this.resourceCache = resourceCache; this.period = period; this.registerPredicate = registerPredicate; + this.executorService = executorService; } private Set getAndCacheResource(P primary, boolean fromGetter) { @@ -71,6 +84,17 @@ private Set getAndCacheResource(P primary, boolean fromGetter) { return values; } + @SuppressWarnings("unchecked") + private void scheduleNextExecution(P primary, Set actualResources) { + var primaryID = ResourceID.fromResource(primary); + var fetchDelay = resourceFetcher.fetchDelay(actualResources, primary); + var fetchDuration = fetchDelay.orElse(Duration.ofMillis(period)); + + ScheduledFuture scheduledFuture = (ScheduledFuture) executorService + .schedule(new FetchingExecutor(primaryID), fetchDuration.toMillis(), TimeUnit.MILLISECONDS); + scheduledFutures.put(primaryID, scheduledFuture); + } + @Override public void onResourceCreated(P resource) { checkAndRegisterTask(resource); @@ -84,10 +108,10 @@ public void onResourceUpdated(P newResource, P oldResource) { @Override public void onResourceDeleted(P resource) { var resourceID = ResourceID.fromResource(resource); - TimerTask task = timerTasks.remove(resourceID); - if (task != null) { - log.debug("Canceling task for resource: {}", resource); - task.cancel(); + var scheduledFuture = scheduledFutures.remove(resourceID); + if (scheduledFuture != null) { + log.debug("Canceling scheduledFuture for resource: {}", resource); + scheduledFuture.cancel(true); } handleDelete(resourceID); fetchedForPrimaries.remove(resourceID); @@ -97,28 +121,45 @@ public void onResourceDeleted(P resource) { // since events from ResourceEventAware are propagated from the thread of the informer. This is // important // because otherwise there will be a race condition related to the timerTasks. + @SuppressWarnings("unchecked") private void checkAndRegisterTask(P resource) { var primaryID = ResourceID.fromResource(resource); - if (timerTasks.get(primaryID) == null && (registerPredicate == null + if (scheduledFutures.get(primaryID) == null && (registerPredicate == null || registerPredicate.test(resource))) { - var task = - new TimerTask() { - @Override - public void run() { - if (!isRunning()) { - log.debug("Event source not yet started. Will not run for: {}", primaryID); - return; - } - // always use up-to-date resource from cache - var res = resourceCache.get(primaryID); - res.ifPresentOrElse(p -> getAndCacheResource(p, false), - () -> log.warn("No resource in cache for resource ID: {}", primaryID)); - } - }; - timerTasks.put(primaryID, task); - // there is a delay, to not do two fetches when the resources first appeared + + + var cachedResources = cache.get(primaryID); + var actualResources = + cachedResources == null ? null : new HashSet<>(cachedResources.values()); + // note that there is a delay, to not do two fetches when the resources first appeared // and getSecondaryResource is called on reconciliation. - timer.schedule(task, period, period); + scheduleNextExecution(resource, actualResources); + } + } + + private class FetchingExecutor implements Runnable { + private final ResourceID primaryID; + + public FetchingExecutor(ResourceID primaryID) { + this.primaryID = primaryID; + } + + @Override + public void run() { + if (!isRunning()) { + log.debug("Event source not yet started. Will not run for: {}", primaryID); + return; + } + // always use up-to-date resource from cache + var primary = resourceCache.get(primaryID); + if (primary.isEmpty()) { + log.warn("No resource in cache for resource ID: {}", primaryID); + // todo think through + test + // no new execution is scheduled in this case, a on delete event should be received shortly + } else { + var actualResources = primary.map(p -> getAndCacheResource(p, false)); + scheduleNextExecution(primary.get(), actualResources.orElse(null)); + } } } @@ -146,12 +187,28 @@ public Set getSecondaryResources(P primary) { public interface ResourceFetcher { Set fetchResources(P primaryResource); + + /** + * By implementing this method it is possible to specify dynamic durations to wait between the + * polls of the resources. This is especially handy if a resources "stabilized" so it is not + * expected to change it's state frequently. For example an AWS RDS instance is up and running, + * it is expected to run and be stable for a very long time. In this case it is enough to poll + * with a lower frequency, compared to the phase when it is being initialized. + * + * @param lastFetchedResource might be null, in case no fetch happened before. Empty set if + * fetch happened but no resources were found. + * @param primary related primary resource + * @return an Optional containing the Duration to wait until the next fetch. If an empty + * Optional is returned, the default polling period will be used. + */ + default Optional fetchDelay(Set lastFetchedResource, P primary) { + return Optional.empty(); + } } @Override public void stop() throws OperatorException { super.stop(); - timer.cancel(); + executorService.shutdownNow(); } - } From e076dadb5a0d88206f136193c3cc954cf79416f4 Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 22 Mar 2023 08:51:38 +0100 Subject: [PATCH 2/8] wip --- .../source/polling/PerResourcePollingEventSourceTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index fa4a624d59..780a4c9518 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -131,4 +131,9 @@ void getsValueFromCacheOrSupplier() throws InterruptedException { verify(eventHandler, times(1)).handleEvent(any()); } + @Test + void dynamicDelaysCanBeImplemented() { + + } + } From e0845ef20eaae0160e8b59057415c9673dae765b Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 22 Mar 2023 10:31:17 +0100 Subject: [PATCH 3/8] refactor tests --- .../PerResourcePollingEventSourceTest.java | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index 780a4c9518..0a835189f7 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -1,5 +1,6 @@ package io.javaoperatorsdk.operator.processing.event.source.polling; +import java.time.Duration; import java.util.Collections; import java.util.Optional; import java.util.Set; @@ -16,6 +17,7 @@ import io.javaoperatorsdk.operator.sample.simple.TestCustomResource; import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; @@ -47,45 +49,50 @@ public void setup() { } @Test - void pollsTheResourceAfterAwareOfIt() throws InterruptedException { + void pollsTheResourceAfterAwareOfIt() { source.onResourceCreated(testCustomResource); - Thread.sleep(3 * PERIOD); - verify(supplier, atLeast(2)).fetchResources(eq(testCustomResource)); - verify(eventHandler, times(1)).handleEvent(any()); + await().pollDelay(Duration.ofMillis(3 * PERIOD)).untilAsserted(() -> { + verify(supplier, atLeast(2)).fetchResources(eq(testCustomResource)); + verify(supplier, atLeast(2)).fetchDelay(any(), eq(testCustomResource)); + verify(eventHandler, times(1)).handleEvent(any()); + }); } @Test - void registeringTaskOnAPredicate() throws InterruptedException { + void registeringTaskOnAPredicate() { setUpSource(new PerResourcePollingEventSource<>(supplier, resourceCache, PERIOD, testCustomResource -> testCustomResource.getMetadata().getGeneration() > 1, SampleExternalResource.class, CacheKeyMapper.singleResourceCacheKeyMapper())); source.onResourceCreated(testCustomResource); - Thread.sleep(2 * PERIOD); - verify(supplier, times(0)).fetchResources(eq(testCustomResource)); + + await().pollDelay(Duration.ofMillis(2 * PERIOD)) + .untilAsserted(() -> verify(supplier, times(0)).fetchResources(eq(testCustomResource))); + testCustomResource.getMetadata().setGeneration(2L); source.onResourceUpdated(testCustomResource, testCustomResource); - Thread.sleep(2 * PERIOD); - verify(supplier, atLeast(1)).fetchResources(eq(testCustomResource)); + await().pollDelay(Duration.ofMillis(2 * PERIOD)) + .untilAsserted(() -> verify(supplier, atLeast(1)).fetchResources(eq(testCustomResource))); } @Test - void propagateEventOnDeletedResource() throws InterruptedException { + void propagateEventOnDeletedResource() { source.onResourceCreated(testCustomResource); when(supplier.fetchResources(any())) .thenReturn(Set.of(SampleExternalResource.testResource1())) .thenReturn(Collections.emptySet()); - Thread.sleep(3 * PERIOD); - verify(supplier, atLeast(2)).fetchResources(eq(testCustomResource)); - verify(eventHandler, times(2)).handleEvent(any()); + await().pollDelay(Duration.ofMillis(3 * PERIOD)).untilAsserted(() -> { + verify(supplier, atLeast(2)).fetchResources(eq(testCustomResource)); + verify(eventHandler, times(2)).handleEvent(any()); + }); } @Test - void getSecondaryResourceInitiatesFetchJustForFirstTime() throws InterruptedException { + void getSecondaryResourceInitiatesFetchJustForFirstTime() { source.onResourceCreated(testCustomResource); when(supplier.fetchResources(any())) .thenReturn(Set.of(SampleExternalResource.testResource1())) @@ -104,31 +111,31 @@ void getSecondaryResourceInitiatesFetchJustForFirstTime() throws InterruptedExce verify(supplier, times(1)).fetchResources(eq(testCustomResource)); verify(eventHandler, never()).handleEvent(any()); - Thread.sleep(PERIOD * 2); - - verify(supplier, atLeast(2)).fetchResources(eq(testCustomResource)); - value = source.getSecondaryResources(testCustomResource); - assertThat(value).hasSize(2); + await().pollDelay(Duration.ofMillis(PERIOD * 2)).untilAsserted(() -> { + verify(supplier, atLeast(2)).fetchResources(eq(testCustomResource)); + var val = source.getSecondaryResources(testCustomResource); + assertThat(val).hasSize(2); + }); } @Test - void getsValueFromCacheOrSupplier() throws InterruptedException { + void getsValueFromCacheOrSupplier() { source.onResourceCreated(testCustomResource); when(supplier.fetchResources(any())) .thenReturn(Collections.emptySet()) .thenReturn(Set.of(SampleExternalResource.testResource1())); - Thread.sleep(PERIOD / 3); - - var value = source.getSecondaryResources(testCustomResource); - verify(eventHandler, times(0)).handleEvent(any()); - assertThat(value).isEmpty(); - - Thread.sleep(PERIOD * 2); - - value = source.getSecondaryResources(testCustomResource); - assertThat(value).hasSize(1); - verify(eventHandler, times(1)).handleEvent(any()); + await().pollDelay(Duration.ofMillis(PERIOD / 3)).untilAsserted(() -> { + var value = source.getSecondaryResources(testCustomResource); + verify(eventHandler, times(0)).handleEvent(any()); + assertThat(value).isEmpty(); + }); + + await().pollDelay(Duration.ofMillis(PERIOD * 2)).untilAsserted(() -> { + var value2 = source.getSecondaryResources(testCustomResource); + assertThat(value2).hasSize(1); + verify(eventHandler, times(1)).handleEvent(any()); + }); } @Test From e1451f9e530c7aecaf392136dadacfdfe92a2337 Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 22 Mar 2023 10:43:29 +0100 Subject: [PATCH 4/8] wip --- .../polling/PerResourcePollingEventSourceTest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index 0a835189f7..1cd6ee4f28 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -139,8 +139,18 @@ void getsValueFromCacheOrSupplier() { } @Test - void dynamicDelaysCanBeImplemented() { + void supportsDynamicPollingDelay() { + when(supplier.fetchResources(any())) + .thenReturn(Set.of(SampleExternalResource.testResource1())); + when(supplier.fetchDelay(any(),any())) + .thenReturn(Optional.of(Duration.ofMillis(PERIOD*2))) + .thenReturn(Optional.of(Duration.ofMillis(PERIOD))); + + source.onResourceCreated(testCustomResource); + await().pollDelay(Duration.ofMillis(PERIOD)).untilAsserted(() -> { + // todo + }); } } From f8fe87625bc9da75ee98ff8c597351c678fcfe6a Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 22 Mar 2023 15:00:35 +0100 Subject: [PATCH 5/8] test added --- .../PerResourcePollingEventSourceTest.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index 1cd6ee4f28..11aa74d99f 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -143,14 +143,30 @@ void supportsDynamicPollingDelay() { when(supplier.fetchResources(any())) .thenReturn(Set.of(SampleExternalResource.testResource1())); when(supplier.fetchDelay(any(),any())) - .thenReturn(Optional.of(Duration.ofMillis(PERIOD*2))) - .thenReturn(Optional.of(Duration.ofMillis(PERIOD))); + .thenReturn(Optional.of(Duration.ofMillis(PERIOD))) + .thenReturn(Optional.of(Duration.ofMillis(PERIOD*2))); source.onResourceCreated(testCustomResource); - await().pollDelay(Duration.ofMillis(PERIOD)).untilAsserted(() -> { - // todo + await().pollDelay(Duration.ofMillis(PERIOD)).atMost(Duration.ofMillis((long) (1.5 * PERIOD))) + .pollInterval(Duration.ofMillis(20)) + .untilAsserted(() -> { + verify(supplier,times(1)).fetchResources(any()); }); + + // verifying that it is not called as with normal interval + await().pollDelay(Duration.ofMillis(PERIOD)).atMost(Duration.ofMillis((long) (1.5*PERIOD))) + .pollInterval(Duration.ofMillis(20)) + .untilAsserted(() -> { + verify(supplier,times(1)).fetchResources(any()); + }); + + await().pollDelay(Duration.ofMillis(PERIOD)).atMost(Duration.ofMillis(2 * PERIOD)) + .pollInterval(Duration.ofMillis(20)) + .untilAsserted(() -> { + verify(supplier,times(2)).fetchResources(any()); + }); + } } From b961b34eb86b5857348358d23586a7d86480d45d Mon Sep 17 00:00:00 2001 From: csviri Date: Wed, 22 Mar 2023 15:20:06 +0100 Subject: [PATCH 6/8] additional test --- .../PerResourcePollingEventSource.java | 7 +--- .../PerResourcePollingEventSourceTest.java | 33 ++++++++++++------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java index 11bb61583e..8026d96a0b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java @@ -119,15 +119,11 @@ public void onResourceDeleted(P resource) { // This method is always called from the same Thread for the same resource, // since events from ResourceEventAware are propagated from the thread of the informer. This is - // important - // because otherwise there will be a race condition related to the timerTasks. - @SuppressWarnings("unchecked") + // important because otherwise there will be a race condition related to the timerTasks. private void checkAndRegisterTask(P resource) { var primaryID = ResourceID.fromResource(resource); if (scheduledFutures.get(primaryID) == null && (registerPredicate == null || registerPredicate.test(resource))) { - - var cachedResources = cache.get(primaryID); var actualResources = cachedResources == null ? null : new HashSet<>(cachedResources.values()); @@ -154,7 +150,6 @@ public void run() { var primary = resourceCache.get(primaryID); if (primary.isEmpty()) { log.warn("No resource in cache for resource ID: {}", primaryID); - // todo think through + test // no new execution is scheduled in this case, a on delete event should be received shortly } else { var actualResources = primary.map(p -> getAndCacheResource(p, false)); diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java index 11aa74d99f..727b60ed9b 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSourceTest.java @@ -150,23 +150,34 @@ void supportsDynamicPollingDelay() { await().pollDelay(Duration.ofMillis(PERIOD)).atMost(Duration.ofMillis((long) (1.5 * PERIOD))) .pollInterval(Duration.ofMillis(20)) - .untilAsserted(() -> { - verify(supplier,times(1)).fetchResources(any()); - }); - + .untilAsserted(() -> verify(supplier,times(1)).fetchResources(any())); // verifying that it is not called as with normal interval await().pollDelay(Duration.ofMillis(PERIOD)).atMost(Duration.ofMillis((long) (1.5*PERIOD))) .pollInterval(Duration.ofMillis(20)) - .untilAsserted(() -> { - verify(supplier,times(1)).fetchResources(any()); - }); - + .untilAsserted(() -> verify(supplier,times(1)).fetchResources(any())); await().pollDelay(Duration.ofMillis(PERIOD)).atMost(Duration.ofMillis(2 * PERIOD)) .pollInterval(Duration.ofMillis(20)) - .untilAsserted(() -> { - verify(supplier,times(2)).fetchResources(any()); - }); + .untilAsserted(() -> verify(supplier,times(2)).fetchResources(any())); + } + + @Test + void deleteEventCancelsTheScheduling() { + when(supplier.fetchResources(any())) + .thenReturn(Set.of(SampleExternalResource.testResource1())); + + source.onResourceCreated(testCustomResource); + + await().pollDelay(Duration.ofMillis(PERIOD)) + .atMost(Duration.ofMillis((2* PERIOD))) + .pollInterval(Duration.ofMillis(20)) + .untilAsserted(() -> verify(supplier,times(1)).fetchResources(any())); + + source.onResourceDeleted(testCustomResource); + // check if not called again. + await().pollDelay(Duration.ofMillis(PERIOD)) + .atMost(Duration.ofMillis((2* PERIOD))) + .untilAsserted(() -> verify(supplier,times(1)).fetchResources(any())); } } From bc0c2f73f10a1b61faa6d6155654c4bd07dc519a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Mon, 27 Mar 2023 08:52:08 +0200 Subject: [PATCH 7/8] Update operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java Co-authored-by: Chris Laprun --- .../event/source/polling/PerResourcePollingEventSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java index 8026d96a0b..520ca14acf 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java @@ -186,7 +186,7 @@ public interface ResourceFetcher { /** * By implementing this method it is possible to specify dynamic durations to wait between the * polls of the resources. This is especially handy if a resources "stabilized" so it is not - * expected to change it's state frequently. For example an AWS RDS instance is up and running, + * expected to change its state frequently. For example an AWS RDS instance is up and running, * it is expected to run and be stable for a very long time. In this case it is enough to poll * with a lower frequency, compared to the phase when it is being initialized. * From ba3710c23da7c67aebb256eb8ce2322b7ef8f6fe Mon Sep 17 00:00:00 2001 From: csviri Date: Mon, 27 Mar 2023 08:52:48 +0200 Subject: [PATCH 8/8] reme comment --- .../event/source/polling/PerResourcePollingEventSource.java | 1 - 1 file changed, 1 deletion(-) diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java index 520ca14acf..ad688599db 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java @@ -27,7 +27,6 @@ * @param the resource polled by the event source * @param

related custom resource */ -// todo check docs public class PerResourcePollingEventSource extends ExternalResourceCachingEventSource implements ResourceEventAware

{