Skip to content

Commit 8ca5767

Browse files
csvirimetacosm
authored andcommitted
feat: re-schedule from error handler (#2023)
Signed-off-by: csviri <[email protected]> Signed-off-by: Attila Mészáros <[email protected]>
1 parent 89e076f commit 8ca5767

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/BaseControl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public abstract class BaseControl<T extends BaseControl<T>> {
99
private Long scheduleDelay = null;
1010

1111
public T rescheduleAfter(long delay) {
12-
this.scheduleDelay = delay;
12+
rescheduleAfter(Duration.ofMillis(delay));
1313
return (T) this;
1414
}
1515

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/ErrorStatusUpdateControl.java

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package io.javaoperatorsdk.operator.api.reconciler;
22

3+
import java.time.Duration;
34
import java.util.Optional;
45

56
import io.fabric8.kubernetes.api.model.HasMetadata;
67

7-
public class ErrorStatusUpdateControl<P extends HasMetadata> {
8+
public class ErrorStatusUpdateControl<P extends HasMetadata>
9+
extends BaseControl<ErrorStatusUpdateControl<P>> {
810

911
private final P resource;
1012
private final boolean patch;
1113
private boolean noRetry = false;
1214

13-
1415
public static <T extends HasMetadata> ErrorStatusUpdateControl<T> patchStatus(T resource) {
1516
return new ErrorStatusUpdateControl<>(resource, true);
1617
}
@@ -49,4 +50,16 @@ public boolean isNoRetry() {
4950
public boolean isPatch() {
5051
return patch;
5152
}
53+
54+
/**
55+
* If re-scheduled using this method, it is not considered as retry, it effectively cancels retry.
56+
*
57+
* @param delay for next execution
58+
* @return ErrorStatusUpdateControl
59+
*/
60+
@Override
61+
public ErrorStatusUpdateControl<P> rescheduleAfter(Duration delay) {
62+
withNoRetry();
63+
return super.rescheduleAfter(delay);
64+
}
5265
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcher.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,17 @@ public boolean isLastAttempt() {
201201
.updateStatus(errorStatusUpdateControl.getResource().orElseThrow());
202202
}
203203
if (errorStatusUpdateControl.isNoRetry()) {
204+
PostExecutionControl<P> postExecutionControl;
204205
if (updatedResource != null) {
205-
return errorStatusUpdateControl.isPatch()
206+
postExecutionControl = errorStatusUpdateControl.isPatch()
206207
? PostExecutionControl.customResourceStatusPatched(updatedResource)
207208
: PostExecutionControl.customResourceUpdated(updatedResource);
208209
} else {
209-
return PostExecutionControl.defaultDispatch();
210+
postExecutionControl = PostExecutionControl.defaultDispatch();
210211
}
212+
errorStatusUpdateControl.getScheduleDelay()
213+
.ifPresent(postExecutionControl::withReSchedule);
214+
return postExecutionControl;
211215
}
212216
} catch (RuntimeException ex) {
213217
log.error("Error during error status handling.", ex);

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/event/ReconciliationDispatcherTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,24 @@ void retriesAddingFinalizer() {
673673
verify(customResourceFacade, times(2)).updateResource(any());
674674
}
675675

676+
@Test
677+
void reSchedulesFromErrorHandler() {
678+
var delay = 1000L;
679+
testCustomResource.addFinalizer(DEFAULT_FINALIZER);
680+
reconciler.reconcile = (r, c) -> {
681+
throw new IllegalStateException("Error Status Test");
682+
};
683+
reconciler.errorHandler =
684+
(r, ri, e) -> ErrorStatusUpdateControl.<TestCustomResource>noStatusUpdate()
685+
.rescheduleAfter(delay);
686+
687+
var res = reconciliationDispatcher.handleExecution(
688+
new ExecutionScope(null).setResource(testCustomResource));
689+
690+
assertThat(res.getReScheduleDelay()).contains(delay);
691+
assertThat(res.getRuntimeException()).isEmpty();
692+
}
693+
676694
private ObservedGenCustomResource createObservedGenCustomResource() {
677695
ObservedGenCustomResource observedGenCustomResource = new ObservedGenCustomResource();
678696
observedGenCustomResource.setMetadata(new ObjectMeta());

0 commit comments

Comments
 (0)