in accord-core/src/main/java/accord/coordinate/RecoverWithRoute.java [126:182]
protected void onDone(Success success, Throwable failure)
{
if (failure != null)
{
callback.accept(null, failure);
return;
}
CheckStatusOkFull merged = (CheckStatusOkFull) this.merged;
Known known = merged.sufficientFor(route);
switch (known.outcome)
{
default: throw new AssertionError();
case OutcomeUnknown:
if (known.definition.isKnown())
{
Txn txn = merged.partialTxn.reconstitute(route);
Recover.recover(node, txnId, txn, route, callback);
}
else
{
if (witnessedByInvalidation != null && witnessedByInvalidation.compareTo(Status.PreAccepted) > 0)
throw new IllegalStateException("We previously invalidated, finding a status that should be recoverable");
Invalidate.invalidate(node, txnId, route, witnessedByInvalidation != null, callback);
}
break;
case OutcomeApplied:
case OutcomeKnown:
Invariants.checkState(known.definition.isKnown());
Invariants.checkState(known.executeAt.hasDecidedExecuteAt());
// TODO (required): we might not be able to reconstitute Txn if we have GC'd on some shards
Txn txn = merged.partialTxn.reconstitute(route);
if (known.deps.hasDecidedDeps())
{
Deps deps = merged.committedDeps.reconstitute(route());
node.withEpoch(merged.executeAt.epoch(), () -> {
Persist.persistAndCommitMaximal(node, txnId, route(), txn, merged.executeAt, deps, merged.writes, merged.result);
});
callback.accept(APPLIED, null);
}
else
{
Recover.recover(node, txnId, txn, route, callback);
}
break;
case InvalidationApplied:
if (witnessedByInvalidation != null && witnessedByInvalidation.hasBeen(Status.PreCommitted))
throw new IllegalStateException("We previously invalidated, finding a status that should be recoverable");
long untilEpoch = node.topology().epoch();
commitInvalidate(node, txnId, route, untilEpoch);
callback.accept(INVALIDATED, null);
break;
}
}