Title: EventFilterWindow suppresses mapper events when controller writes through shared InformerEventSource · Issue #3445 · operator-framework/java-operator-sdk · GitHub
Open Graph Title: EventFilterWindow suppresses mapper events when controller writes through shared InformerEventSource · Issue #3445 · operator-framework/java-operator-sdk
X Title: EventFilterWindow suppresses mapper events when controller writes through shared InformerEventSource · Issue #3445 · operator-framework/java-operator-sdk
Description: Description When a controller patches a secondary resource's status through its own InformerEventSource (via eventFilteringUpdateAndCacheResource), the EventFilterWindow correctly identifies the resulting informer event as an "own update...
Open Graph Description: Description When a controller patches a secondary resource's status through its own InformerEventSource (via eventFilteringUpdateAndCacheResource), the EventFilterWindow correctly identifies the re...
X Description: Description When a controller patches a secondary resource's status through its own InformerEventSource (via eventFilteringUpdateAndCacheResource), the EventFilterWindow correctly identifies th...
Opengraph URL: https://github.com/operator-framework/java-operator-sdk/issues/3445
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"EventFilterWindow suppresses mapper events when controller writes through shared InformerEventSource","articleBody":"## Description\n\nWhen a controller patches a secondary resource's status through its own `InformerEventSource` (via `eventFilteringUpdateAndCacheResource`), the `EventFilterWindow` correctly identifies the resulting informer event as an \"own update\" and suppresses it. However, this suppression also prevents the `SecondaryToPrimaryMapper` from ever seeing the updated resource state, which can leave the controller in a dead state.\n\n## Scenario\n\nA controller reconciles a primary resource and has an `InformerEventSource` for a secondary resource type. The mapper uses a generation/observedGeneration guard:\n\n- `generation != observedGeneration` → return empty set (secondary not ready, skip)\n- `generation == observedGeneration` → return primary ResourceID (secondary ready, trigger)\n\nDuring reconciliation the controller patches the secondary's `status.observedGeneration` to match `metadata.generation` through its `InformerEventSource`. The `EventFilterWindow` suppresses the resulting event as an own update. The mapper never sees `gen == obsGen`, so the controller is never re-triggered.\n\n## Expected behaviour\n\nThe status-change event should reach the mapper so it can evaluate the new state and trigger reconciliation of the primary.\n\n## Actual behaviour\n\nThe `EventFilterWindow` suppresses the event because its resource version matches `ownUpdateVersions`. The mapper never fires. The controller enters a dead state for that secondary resource.\n\n## Root cause\n\n`ManagedInformerEventSource.eventFilteringUpdateAndCacheResource` (line 96) opens a filter window, performs the update, records the response resource version as an \"own\" version, then closes the window. When the informer event arrives with that resource version, `EventFilterWindow.eventForRangeAndClear` (line 183) sees `events.keySet().equals(ownResourceVersions)` and returns `Optional.empty()` — the event is swallowed before it reaches `propagateEvent` and the mapper.\n\n## Impact\n\nThis affects any controller that:\n1. Writes to a secondary resource through its own `InformerEventSource` (directly or via a `KubernetesDependentResource` sharing the event source with `useEventSourceWithName`)\n2. Has a mapper that depends on seeing the result of that write\n\nThe pattern is common in controllers that manage secondary resources and use generation/observedGeneration guards to sequence reconciliation.\n\n## Reproducer\n\nBranch: `reproducer/status-event-filtering` — see `StatusEventFilteringIT` in `operator-framework/src/test/java/.../baseapi/statuseventfiltering/`\n\n## Downstream issue\n\nhttps://github.com/kroxylicious/kroxylicious/issues/4241\n\nHappy to look at a fix if the maintainers agree with the analysis.","author":{"url":"https://github.com/SamBarker","@type":"Person","name":"SamBarker"},"datePublished":"2026-06-29T05:35:01.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/3445/java-operator-sdk/issues/3445"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:25abca47-8a32-51a0-7088-7b66139927a1 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8D00:166C0A:4A9E694:68FC50B:6A56E8F2 |
| html-safe-nonce | fb2dc1b41c8aeba76d86dc14298fcd657b68bdb5f5668657b7a8763a3849e563 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4RDAwOjE2NkMwQTo0QTlFNjk0OjY4RkM1MEI6NkE1NkU4RjIiLCJ2aXNpdG9yX2lkIjoiNDMzNTYwNTM0NjMzMDkyOTM5NCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | fe24c0d10d57c6798d8ed429e600ff42d6b091e6a8dcc2586517b5e736040dca |
| hovercard-subject-tag | issue:4765326724 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/operator-framework/java-operator-sdk/3445/issue_layout |
| twitter:image | https://opengraph.githubassets.com/b1374c6c9638fef7c2621d6db26fa2f9e34e58d5089f56f40bba5f6fff87286e/operator-framework/java-operator-sdk/issues/3445 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/b1374c6c9638fef7c2621d6db26fa2f9e34e58d5089f56f40bba5f6fff87286e/operator-framework/java-operator-sdk/issues/3445 |
| og:image:alt | Description When a controller patches a secondary resource's status through its own InformerEventSource (via eventFilteringUpdateAndCacheResource), the EventFilterWindow correctly identifies the re... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | SamBarker |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5220a278731283038daf0ed00b41f06ef7ff9539020ecc806c5c5a0fb6bda25a |
| turbo-cache-control | no-preview |
| go-import | github.com/operator-framework/java-operator-sdk git https://github.com/operator-framework/java-operator-sdk.git |
| octolytics-dimension-user_id | 38202270 |
| octolytics-dimension-user_login | operator-framework |
| octolytics-dimension-repository_id | 188592933 |
| octolytics-dimension-repository_nwo | operator-framework/java-operator-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 188592933 |
| octolytics-dimension-repository_network_root_nwo | operator-framework/java-operator-sdk |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 8684ae1a81cd3e4ef219b241179982bbda1a5b1f |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width