|
11 | 11 | import io.fabric8.kubernetes.client.dsl.base.PatchContext; |
12 | 12 | import io.fabric8.kubernetes.client.dsl.base.PatchType; |
13 | 13 | import io.javaoperatorsdk.operator.OperatorException; |
| 14 | +import io.javaoperatorsdk.operator.api.config.ConfigurationService; |
14 | 15 | import io.javaoperatorsdk.operator.api.reconciler.support.PrimaryResourceCache; |
15 | 16 | import io.javaoperatorsdk.operator.processing.event.ResourceID; |
16 | 17 |
|
|
19 | 20 | * sure that fresh resource is present for the next reconciliation. The main use case for such |
20 | 21 | * updates is to store state is resource status. We aim here for completeness and provide you all |
21 | 22 | * various options, where all of them have pros and cons. |
| 23 | + * |
| 24 | + * <ul> |
| 25 | + * <li>Retryable updates with optimistic locking (*withLock) - you can use this approach out of |
| 26 | + * the box, it updates the resource using optimistic locking and caches the resource. If the |
| 27 | + * update fails it reads the primary resource and applies the modifications again and retries |
| 28 | + * the update. After successful update it caches the resource for next reconciliation. The |
| 29 | + * disadvantage of this method is that theoretically it could fail the max attempt retry. Note |
| 30 | + * that optimistic locking is essential to have the caching work in general. |
| 31 | + * <li>Caching without optimistic locking but with parsing the resource version - to use this you |
| 32 | + * have to set {@link ConfigurationService#parseResourceVersionsForEventFilteringAndCaching()} |
| 33 | + * to true. The update won't fail on optimistic locking so there is much higher chance to |
| 34 | + * succeed. However this bends the rules of Kubernetes API contract by parsing the resource |
| 35 | + * version. Using this for this purpose is actually a gray area, it should be fine in most of |
| 36 | + * the setups. |
| 37 | + * <li>Using {@link PrimaryResourceCache} - in this way you can explicitly ensure freshness or the |
| 38 | + * resource (see related docs). You don't have to use optimistic locking or parse the resource |
| 39 | + * version. But requires code from your side and for now (might in future) is not supported in |
| 40 | + * managed dependent resources. |
| 41 | + * </ul> |
22 | 42 | */ |
23 | 43 | public class PrimaryUpdateAndCacheUtils { |
24 | 44 |
|
@@ -75,11 +95,15 @@ public static <P extends HasMetadata> P patchStatusAndCacheResourceWithLock( |
75 | 95 | primary, context, modificationFunction, r -> context.getClient().resource(r).patchStatus()); |
76 | 96 | } |
77 | 97 |
|
78 | | - // TODO document caveat with JSON PATCH |
79 | 98 | /** |
80 | 99 | * Patches status and makes sure that the up-to-date primary resource will be present during the |
81 | 100 | * next reconciliation. Using JSON Patch. |
82 | 101 | * |
| 102 | + * <p>Note that since optimistic locking is not used, there is a risk that JSON Patch will have |
| 103 | + * concurrency issues when removing an element from a list. Since, the list element in JSON Patch |
| 104 | + * are addressed by index, so if a concurrent request removes an element with lower index, the |
| 105 | + * request might be not valid anymore (HTTP 422) or might remove an unmeant element. |
| 106 | + * |
83 | 107 | * @param primary resource |
84 | 108 | * @param context of reconciliation |
85 | 109 | * @return updated resource |
|
0 commit comments