ONOS-6468 Fix for race condition between compilation and installation complete state.
- Fix for a bug where intent compilation complete state,
can overwrites intent installation complete state,
if intent installation completes before compilation complete state is written to the store.
- Introduced internalState version on IntentData,
which is effectively mutation count, in order to avoid
batch write of compilation result overwriting installation result
Change-Id: I5d77dfbe496e690ebdf2b4f9643d2b64c4233182
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 7b09a1a..0cae8da 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -239,7 +239,7 @@
public void submit(Intent intent) {
checkPermission(INTENT_WRITE);
checkNotNull(intent, INTENT_NULL);
- IntentData data = new IntentData(intent, IntentState.INSTALL_REQ, null);
+ IntentData data = IntentData.submit(intent);
store.addPending(data);
}
@@ -247,7 +247,7 @@
public void withdraw(Intent intent) {
checkPermission(INTENT_WRITE);
checkNotNull(intent, INTENT_NULL);
- IntentData data = new IntentData(intent, IntentState.WITHDRAW_REQ, null);
+ IntentData data = IntentData.withdraw(intent);
store.addPending(data);
}
@@ -255,7 +255,7 @@
public void purge(Intent intent) {
checkPermission(INTENT_WRITE);
checkNotNull(intent, INTENT_NULL);
- IntentData data = new IntentData(intent, IntentState.PURGE_REQ, null);
+ IntentData data = IntentData.purge(intent);
store.addPending(data);
// remove associated group if there is one
@@ -495,6 +495,8 @@
@Override
public void triggerCompile(Iterable<Key> intentKeys,
boolean compileAllFailed) {
+ // TODO figure out who is making excessive calls?
+ log.trace("submitting {} + all?:{}", intentKeys, compileAllFailed);
buildAndSubmitBatches(intentKeys, compileAllFailed);
}
}
@@ -509,6 +511,10 @@
CompletableFuture.runAsync(() -> {
// process intent until the phase reaches one of the final phases
List<CompletableFuture<IntentData>> futures = operations.stream()
+ .map(data -> {
+ log.debug("Start processing of {} {}@{}", data.request(), data.key(), data.version());
+ return data;
+ })
.map(x -> CompletableFuture.completedFuture(x)
.thenApply(IntentManager.this::createInitialPhase)
.thenApplyAsync(IntentProcessPhase::process, workerExecutor)
@@ -525,9 +531,9 @@
case INSTALLING:
case WITHDRAW_REQ:
case WITHDRAWING:
- x.setState(FAILED);
+ // TODO should we swtich based on current
IntentData current = store.getIntentData(x.key());
- return new IntentData(x, current.installables());
+ return IntentData.nextState(current, FAILED);
default:
return null;
}