Skip to content

Commit cbac64f

Browse files
committed
fix: use a monotonic clock for the cache polling timeout
`pollLocalCache` computed its deadline with `LocalTime`: var startTime = LocalTime.now(); final var timeoutTime = startTime.plus(timeoutMillis, ChronoUnit.MILLIS); while (timeoutTime.isAfter(LocalTime.now())) { `LocalTime` is a time of day and wraps at midnight, so for any call made within `timeoutMillis` of 00:00 the computed deadline is *earlier* than the current time. The loop body never runs and the method throws `OperatorException("Timeout of resource polling from cache for resource")` immediately, failing the update it was retrying even though the resource would have appeared in cache. With the default 10s timeout that is a 10-second window each day. `LocalTime.now()` is also wall-clock based, so an NTP step or a DST change can shorten or extend the timeout. Switches to `System.nanoTime()`, which is monotonic and has no wrap-around concern, using overflow-safe subtraction for the comparison. No test is added: reproducing this requires controlling the clock, and the class is already deprecated for removal.
1 parent 3e85d04 commit cbac64f

1 file changed

Lines changed: 3 additions & 5 deletions

File tree

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/PrimaryUpdateAndCacheUtils.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
package io.javaoperatorsdk.operator.api.reconciler;
1717

1818
import java.lang.reflect.InvocationTargetException;
19-
import java.time.LocalTime;
20-
import java.time.temporal.ChronoUnit;
19+
import java.util.concurrent.TimeUnit;
2120
import java.util.function.Predicate;
2221
import java.util.function.UnaryOperator;
2322

@@ -232,9 +231,8 @@ private static <P extends HasMetadata> P pollLocalCache(
232231
Context<P> context, P staleResource, long timeoutMillis, long pollDelayMillis) {
233232
try {
234233
var resourceId = ResourceID.fromResource(staleResource);
235-
var startTime = LocalTime.now();
236-
final var timeoutTime = startTime.plus(timeoutMillis, ChronoUnit.MILLIS);
237-
while (timeoutTime.isAfter(LocalTime.now())) {
234+
final var deadlineNanos = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeoutMillis);
235+
while (System.nanoTime() - deadlineNanos < 0) {
238236
log.debug("Polling cache for resource: {}", resourceId);
239237
var cachedResource = context.getPrimaryCache().get(resourceId).orElseThrow();
240238
if (!cachedResource

0 commit comments

Comments
 (0)