Skip to content

Commit f35e8f4

Browse files
committed
wip
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent 51db943 commit f35e8f4

15 files changed

Lines changed: 453 additions & 257 deletions

File tree

.github/workflows/integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
name: Integration tests (${{ inputs.java-version }}, ${{ inputs.kube-version }}, ${{ inputs.http-client }})
2828
runs-on: ubuntu-latest
2929
continue-on-error: ${{ inputs.experimental }}
30-
timeout-minutes: 40
30+
timeout-minutes: 120
3131
steps:
3232
- uses: actions/checkout@v7
3333
with:

docs/content/en/docs/documentation/reconciler.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,37 @@ supports stronger guarantees, both for primary and secondary resources. If this
192192
they would otherwise look like own echoes, since the relist may have
193193
hidden events.
194194

195+
#### Requesting event filtering and its correctness requirements
196+
197+
Own-event filtering is only safe if the framework can tell an own write apart from a concurrent
198+
third-party write. This requires **either**:
199+
200+
- a *matcher* to be provided (so a filtered event can be confirmed to reflect the desired state we
201+
just wrote), **or**
202+
- the update to be done using *optimistic locking* (a resource version set on the written resource),
203+
so a conflicting concurrent change is rejected by the API server rather than silently swallowed.
204+
205+
`ResourceOperations` methods accept an `Options` argument to select the behavior; each maps to a
206+
`Mode`:
207+
208+
- `Options.matchAndFilter(matcher)` / `Options.matchAndFilterWithDefaultMatcher(updateType)` — compare
209+
the desired state to the actual (cached) state; if they already match, skip the write entirely,
210+
otherwise write and filter the own event. This is the **default** for the `ResourceOperations`
211+
update/patch methods, and generally the most efficient option: it filters the own event *and*
212+
avoids a request to the API server when nothing changed. Default matchers are provided for every
213+
operation type, but they are heuristics — a workflow relying on them should be tested against the
214+
concrete resources it manages, or a custom matcher supplied.
215+
- `Options.filterIfOptimisticLocking()` — filter the own event only when the write uses optimistic
216+
locking, otherwise just cache the response.
217+
- `Options.cacheOnly()` — only cache the response (read-cache-after-write consistency), no own-event
218+
filtering.
219+
- `Options.forceFilterEvents()` — always filter, regardless of optimistic locking. Only safe when
220+
correctness is otherwise guaranteed (mostly for internal usage); a concurrent external update in
221+
the filter window may otherwise be missed until the next resync.
222+
223+
See the [`ResourceOperations`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java)
224+
and `ResourceOperations.Options` documentation for details.
225+
195226

196227
In order to benefit from these stronger guarantees, use [`ResourceOperations`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ResourceOperations.java)
197228
from the context of the reconciliation:
@@ -208,20 +239,26 @@ public UpdateControl<WebPage> reconcile(WebPage webPage, Context<WebPage> contex
208239
var upToDateResource = context.getSecondaryResource(ConfigMap.class);
209240

210241
makeStatusChanges(webPage);
211-
212-
// built in update methods by default use this feature
242+
// patches the status and caches the response (does not filter the own event by default, see below)
213243
return UpdateControl.patchStatus(webPage);
214244
}
215245
```
216246

217-
`UpdateControl` and `ErrorStatusUpdateControl` by default use this functionality, but you can also update your primary resource at any time during the reconciliation using `ResourceOperations`:
247+
{{% alert title="UpdateControl and event filtering" %}}
248+
Since v5.5, returning an `UpdateControl` (or `ErrorStatusUpdateControl`) updates the resource and
249+
keeps the cache read-after-write consistent, but by default it **no longer filters the own event**
250+
the resulting update may cause an additional (idempotent) reconciliation. To also filter the own
251+
event, perform the update through `ResourceOperations` instead and return `UpdateControl.noUpdate()`.
252+
{{% /alert %}}
253+
254+
You can update your primary resource at any time during the reconciliation using `ResourceOperations`:
218255

219256
```java
220257

221258
public UpdateControl<WebPage> reconcile(WebPage webPage, Context<WebPage> context) {
222259

223260
makeStatusChanges(webPage);
224-
// this is equivalent to UpdateControl.patchStatus(webpage)
261+
// updates the status, filters the own event and skips the write if nothing changed
225262
context.resourceOperations().serverSideApplyPrimaryStatus(webPage);
226263
return UpdateControl.noUpdate();
227264
}

0 commit comments

Comments
 (0)