Skip to content

Commit 7c16b30

Browse files
committed
fix: bug with the ready
1 parent 1064707 commit 7c16b30

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowReconcileExecutor.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class WorkflowReconcileExecutor<P extends HasMetadata> {
2222

2323
private final Set<DependentResourceNode<?, ?>> alreadyReconciled = ConcurrentHashMap.newKeySet();
2424
private final Set<DependentResourceNode<?, ?>> errored = ConcurrentHashMap.newKeySet();
25-
private final Set<DependentResourceNode<?, ?>> reconciledButNotReady =
25+
private final Set<DependentResourceNode<?, ?>> notReady =
2626
ConcurrentHashMap.newKeySet();
2727
private final Set<DependentResourceNode<?, ?>> reconcileConditionOrParentsConditionNotMet =
2828
ConcurrentHashMap.newKeySet();
@@ -73,8 +73,8 @@ private synchronized void handleReconcile(
7373

7474
if (alreadyReconciled(dependentResourceNode)
7575
|| isReconcilingNow(dependentResourceNode)
76-
|| !allDependsReconciledAndReady(dependentResourceNode)
77-
|| hasErroredDependOn(dependentResourceNode)) {
76+
|| !allParentsReconciledAndReady(dependentResourceNode)
77+
|| hasErroredParent(dependentResourceNode)) {
7878
log.debug("Skipping submit of: {}, ", dependentResourceNode);
7979
return;
8080
}
@@ -103,16 +103,26 @@ private synchronized void handleExceptionInExecutor(DependentResourceNode depend
103103
}
104104

105105
private synchronized void handleNodeExecutionFinish(DependentResourceNode dependentResourceNode) {
106+
log.debug("Finished execution for: {}", dependentResourceNode);
106107
actualExecutions.remove(dependentResourceNode);
107108
if (actualExecutions.isEmpty()) {
108109
this.notifyAll();
109110
}
110111
}
111112

113+
// needs to be synced
112114
private synchronized void updateStatusForNotReady(ReadyCondition<?, P> readyCondition) {
113115
readyCondition.addNotReadyStatusInfo(primary);
114116
}
115117

118+
// needs to be in one step
119+
private synchronized void setAlreadyReconciledButNotReady(
120+
DependentResourceNode<?, P> dependentResourceNode) {
121+
log.debug("Setting already reconciled but not ready for: {}", dependentResourceNode);
122+
alreadyReconciled.add(dependentResourceNode);
123+
notReady.add(dependentResourceNode);
124+
}
125+
116126
private boolean ownOrParentsReconcileConditionNotMet(
117127
DependentResourceNode<?, ?> dependentResourceNode) {
118128
return reconcileConditionOrParentsConditionNotMet.contains(dependentResourceNode) ||
@@ -136,7 +146,7 @@ private NodeExecutor(DependentResourceNode<?, P> dependentResourceNode,
136146
public void run() {
137147
try {
138148
DependentResource dependentResource = dependentResourceNode.getDependentResource();
139-
boolean handleDependents = true;
149+
boolean ready = true;
140150
if (onlyReconcileForPossibleDelete) {
141151
if (dependentResource instanceof Deleter) {
142152
((Deleter<P>) dependentResource).delete(primary, context);
@@ -146,15 +156,17 @@ public void run() {
146156
if (dependentResourceNode.getReadyCondition().isPresent()
147157
&& !dependentResourceNode.getReadyCondition().get()
148158
.isMet(dependentResource, primary, context)) {
149-
handleDependents = false;
150-
reconciledButNotReady.add(dependentResourceNode);
151-
// needs to be synced
159+
ready = false;
152160
updateStatusForNotReady(dependentResourceNode.getReadyCondition().get());
153161
}
154162
}
155-
alreadyReconciled.add(dependentResourceNode);
156-
if (handleDependents) {
163+
164+
if (ready) {
165+
log.debug("Setting already reconciled for: {}", dependentResourceNode);
166+
alreadyReconciled.add(dependentResourceNode);
157167
handleDependentsReconcile(dependentResourceNode, onlyReconcileForPossibleDelete);
168+
} else {
169+
setAlreadyReconciledButNotReady(dependentResourceNode);
158170
}
159171
} catch (RuntimeException e) {
160172
handleExceptionInExecutor(dependentResourceNode, e);
@@ -172,7 +184,11 @@ private synchronized void handleDependentsReconcile(
172184
DependentResourceNode<?, P> dependentResourceNode, boolean onlyReconcileForPossibleDelete) {
173185
var dependents = workflow.getDependents().get(dependentResourceNode);
174186
if (dependents != null) {
175-
dependents.forEach(d -> handleReconcile(d, onlyReconcileForPossibleDelete));
187+
188+
dependents.forEach(d -> {
189+
log.debug("Handle reconcile for dependent: {} of parent:{}", d, dependentResourceNode);
190+
handleReconcile(d, onlyReconcileForPossibleDelete);
191+
});
176192
}
177193
}
178194

@@ -199,15 +215,14 @@ private void handleReconcileCondition(DependentResourceNode<?, ?> dependentResou
199215
}
200216
}
201217

202-
private boolean allDependsReconciledAndReady(
218+
private boolean allParentsReconciledAndReady(
203219
DependentResourceNode<?, ?> dependentResourceNode) {
204220
return dependentResourceNode.getDependsOn().isEmpty()
205221
|| dependentResourceNode.getDependsOn().stream()
206-
.allMatch(d -> alreadyReconciled(d)
207-
&& !reconciledButNotReady.contains(dependentResourceNode));
222+
.allMatch(d -> alreadyReconciled(d) && !notReady.contains(d));
208223
}
209224

210-
private boolean hasErroredDependOn(
225+
private boolean hasErroredParent(
211226
DependentResourceNode<?, ?> dependentResourceNode) {
212227
return !dependentResourceNode.getDependsOn().isEmpty()
213228
&& dependentResourceNode.getDependsOn().stream()

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/workflow/WorkflowTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ void onlyOneDependsOnErroredResourceNotReconciled() {
162162
var workflow = new WorkflowBuilder<TestCustomResource>()
163163
.addDependent(dr1).build()
164164
.addDependent(drError).build()
165-
.addDependent(dr2).dependsOn(drError).dependsOn(dr1).build()
165+
.addDependent(dr2).dependsOn(drError, dr1).build()
166166
.build();
167167
assertThrows(AggregatedOperatorException.class,
168168
() -> workflow.reconcile(new TestCustomResource(), null));
@@ -313,17 +313,17 @@ void diamondShareWithReadyCondition() {
313313
TestDependent dr4 = new TestDependent("DR_4");
314314

315315
var workflow = new WorkflowBuilder<TestCustomResource>()
316-
.addDependent(dr1).build()
317-
.addDependent(dr2).dependsOn(dr1).withReadyCondition(notMetReadyCondition).build()
318-
.addDependent(dr3).dependsOn(dr1).build()
319-
.addDependent(dr4).dependsOn(dr2,dr3).build()
320-
.build();
316+
.addDependent(dr1).build()
317+
.addDependent(dr2).dependsOn(dr1).withReadyCondition(notMetReadyCondition).build()
318+
.addDependent(dr3).dependsOn(dr1).build()
319+
.addDependent(dr4).dependsOn(dr2, dr3).build()
320+
.build();
321321

322322
workflow.reconcile(new TestCustomResource(), null);
323323

324324
assertThat(executionHistory).reconciledInOrder(dr1, dr2)
325-
.reconciledInOrder(dr1, dr3)
326-
.notReconciled(dr4);
325+
.reconciledInOrder(dr1, dr3)
326+
.notReconciled(dr4);
327327
}
328328

329329
private class TestDependent implements DependentResource<String, TestCustomResource> {

0 commit comments

Comments
 (0)