Skip to content

fix: keep polling a resource after its fetcher failed and allow re-registering one absent from the cache - #3668

Open
csviri wants to merge 1 commit into
nextfrom
fix/per-resource-polling-resilience
Open

csviri wants to merge 1 commit into
nextfrom
fix/per-resource-polling-resilience

Conversation

@csviri

@csviri csviri commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Two independent fixes in PerResourcePollingEventSource.FetchingExecutor, extracted from the virtual thread support PR (#3664) so they can be reviewed and merged on their own.

1. A failing fetcher no longer stops the polling of a resource

FetchingExecutor.run() called getAndCacheResource(...) without any error handling. If the ResourceFetcher threw a RuntimeException, scheduleNextExecution(...) was never reached, so the resource silently stopped being polled until it was deleted and recreated.

The exception is now caught and logged, and the next poll is scheduled as usual.

2. A resource absent from the cache can be registered again

When the primary resource is not found in the primary cache, FetchingExecutor logs a warning and does not schedule a new execution, but the completed ScheduledFuture stayed in scheduledFutures. As registerTask only registers a resource when there is no entry for it, a recreated resource with the same ResourceID could never be registered again.

The stale entry is now removed in that case.

Behavior change

  • Fetcher exceptions are logged with log.error and no longer silently end the polling of the resource.
  • No API changes.

Tests

Added to PerResourcePollingEventSourceTest:

  • keepsPollingAfterTheFetcherFailed: the first fetch throws, and the test verifies that polling continues (at least 3 fetches).
  • resourceAbsentFromTheCacheCanBeRegisteredAgain: the primary is missing from the cache, then comes back, and the test verifies that the resource is polled after being registered again.

PerResourcePollingEventSourceTest passes (9 tests).

…gistering one absent from the cache

- a failing resource fetcher no longer ends the polling of that resource
- a stale scheduled entry is dropped when the primary is not in the cache, so a recreated resource can be registered again

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 29, 2026
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0805ce48-e570-4e02-93aa-69eb7b4d83a7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@csviri
csviri marked this pull request as ready for review October 30, 2026 13:30
Copilot AI balanced review requested due to automatic review settings October 30, 2026 13:30
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 30, 2026
@openshift-ci
openshift-ci Bot requested review from metacosm and xstefank October 30, 2026 13:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A polling-registration race can erase a replacement registration and leave duplicate, uncancellable polling chains, while the timing-dependent regression test can miss the bug.

2 open issues
What changed in this PR

This PR extracts two polling fixes from #3664 to improve recovery in the SDK’s per-resource polling event source without changing its API.

Changes:

  • Logs fetcher exceptions and continues scheduling polls.
  • Removes stale scheduling entries when a primary resource is absent from the cache, allowing re-registration.
  • Adds regression tests for both recovery scenarios.
File Description
operator-framework-core/​src/​test/​java/​io/​javaoperatorsdk/​operator/​processing/​event/​source/​polling/​PerResourcePollingEventSourceTest.java Adds tests for continued polling and re-registration.
operator-framework-core/​src/​main/​java/​io/​javaoperatorsdk/​operator/​processing/​event/​source/​polling/​PerResourcePollingEventSource.java Handles fetch failures and clears missing-resource registrations.

Review effort: Balanced

// no new execution is scheduled in this case, an on delete event should be received
// shortly;
// the entry is dropped so that it can't block a registration of a recreated resource
scheduledFutures.remove(primaryID);
Comment on lines +107 to +109
await()
.pollDelay(Duration.ofMillis(2 * PERIOD))
.untilAsserted(() -> verify(supplier, never()).fetchResources(any()));

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants