You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/content/en/docs/documentation/reconciler.md
+90-13Lines changed: 90 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -160,7 +160,84 @@ annotation. If you do not specify a finalizer name, one will be automatically ge
160
160
161
161
From v5, by default, the finalizer is added using Server Side Apply. See also `UpdateControl` in docs.
162
162
163
-
### Making sure the primary resource is up to date for the next reconciliation
163
+
### Read-cache-after-write consistency and event filtering
164
+
165
+
It is an inherent issue with Informers that their caches are eventually consistent even
166
+
with the updates to Kubernetes API done from the controller. From version 5.3.0 the framework
167
+
supports stronger guarantees, both for primary and secondary resources. If this feature is used:
168
+
169
+
1. Reading from the cache after our update — even within the same reconciliation — returns a fresh resource.
170
+
"Fresh" means at least the version of the resource that is in the response from our update,
171
+
or a more recent version if some other party updated the resource after our update. In particular, this means that
172
+
you can safely store state (e.g. generated IDs) in the status sub-resource of your resources since it is now
173
+
guaranteed that the stored values will be observable during the next reconciliation.
174
+
2. Filtering events for our updates. When a controller updates a resource an event is produced by the Kubernetes API and
175
+
propagated to Informer. This would normally trigger another reconciliation. This is, however, not optimal since we
176
+
already have that up-to-date resource in the current reconciliation cache. There is generally no need to reconcile
177
+
that resource again. This feature also makes sure that the reconciliation is not triggered from the event from our
178
+
writes.
179
+
180
+
181
+
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)
// fresh resource instantly available from our update in the cache
193
+
var upToDateResource = context.getSecondaryResource(ConfigMap.class);
194
+
195
+
makeStatusChanges(webPage);
196
+
197
+
// built in update methods by default use this feature
198
+
returnUpdateControl.patchStatus(webPage);
199
+
}
200
+
```
201
+
202
+
`UpdateControl` and `ErrorStatusUpdateControl` by default use this functionality, but you can also update your primary resource at any time during the reconciliation using `ResourceOperations`:
If your reconciler is built around the assumption that new reconciliations would occur after its own updates, a new
216
+
`reschedule` method is provided on `UpdateControl` to immediately reschedule a new reconciliation, to mimic the previous
217
+
behavior.
218
+
219
+
### Caveats
220
+
221
+
- This feature is implemented on top of the Fabric8 client informers, using additional caches in `InformerEventSource`,
222
+
so it is safe to use `context.getSecondaryResources(..)` or `InformerEventSource.get(ResourceID)`methods. Listing
223
+
resources directly via `InformerEventSource.list(..)`, however, won't work since this method directly reads from the
224
+
underlying informer cache, thus bypassing the additional caches that make the feature possible.
225
+
226
+
227
+
### Notes
228
+
- This [talk](https://www.youtube.com/watch?v=HrwHh5Yh6AM&t=1387s) mentions this feature.
229
+
-[Umbrella issue](https://github.com/operator-framework/java-operator-sdk/issues/2944) on GitHub.
230
+
- We were able to implement this feature since Kubernetes introduces guideline to compare
231
+
resource versions. See the details [here](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5504-comparable-resource-version).
232
+
233
+
### Making sure the primary resource is up to date for the next reconciliation (deprecated)
234
+
235
+
{{% alert title="Deprecated" %}}
236
+
237
+
Read-cache-after-write consistency feature replaces this functionality.
238
+
239
+
> It provides this functionality also for secondary resources and optimistic locking is not required anymore. See details above.
240
+
{{% /alert %}}
164
241
165
242
It is typical to want to update the status subresource with the information that is available during the reconciliation.
166
243
This is sometimes referred to as the last observed state. When the primary resource is updated, though, the framework
@@ -263,30 +340,30 @@ See also [sample](https://github.com/operator-framework/java-operator-sdk/blob/m
263
340
### Expectations
264
341
265
342
Expectations are a pattern to ensure that, during reconciliation, your secondary resources are in a certain state.
266
-
For a more detailed explanation see [this blogpost](https://ahmet.im/blog/controller-pitfalls/#expectations-pattern).
267
-
You can find framework support for this pattern in [`io.javaoperatorsdk.operator.processing.expectation`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/)
268
-
package. See also related [integration test](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/expectation/ExpectationReconciler.java).
269
-
Note that this feature is marked as `@Experimental`, since based on feedback the API might be improved / changed, but we intend
270
-
to support it, later also might be integrated to Dependent Resources and/or Workflows.
343
+
For a more detailed explanation, see [this blogpost](https://ahmet.im/blog/controller-pitfalls/#expectations-pattern).
344
+
You can find framework support for this pattern in the [`io.javaoperatorsdk.operator.processing.expectation`](https://github.com/operator-framework/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/expectation/)
345
+
package. See also the related [integration test](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/expectation/onallevent/ExpectationReconciler.java).
346
+
Note that this feature is marked as `@Experimental`: based on feedback the API may be improved or changed, but we intend
347
+
to keep supporting it and may later integrate it into Dependent Resources and/or Workflows.
271
348
272
-
The idea is the nutshell, is that you can track your expectations in the expectation manager in the reconciler
273
-
which has an API that covers the common use cases.
349
+
The idea, in a nutshell, is that you can track your expectations in the expectation manager within the reconciler,
350
+
which provides an API covering the common use cases.
274
351
275
-
The following sample is the simplified version of the integration test that implements the logic that creates a
276
-
deployment and sets status message if there are the target three replicas ready:
352
+
The following is a simplified version of the integration test that implements the logic to create a
353
+
deployment and set a status message once the target three replicas are ready:
0 commit comments