in accord-core/src/main/java/accord/local/Commands.java [870:932]
public void accept(SafeCommandStore safeStore)
{
SafeCommand prevSafe = get(safeStore, depth - 1);
while (depth >= 0)
{
Command prev = prevSafe != null ? prevSafe.current() : null;
SafeCommand curSafe = ifLoaded(safeStore, depth);
Command cur = curSafe != null ? curSafe.current() : null;
Known until = blockedUntil[depth];
if (cur == null)
{
// need to load; schedule execution for later
safeStore.commandStore().execute(this, this).begin(safeStore.agent());
return;
}
if (prev != null)
{
if (cur.has(until) || (cur.hasBeen(PreCommitted) && cur.executeAt().compareTo(prev.executeAt()) > 0))
{
updateDependencyAndMaybeExecute(safeStore, prevSafe, curSafe, false);
--depth;
prevSafe = get(safeStore, depth - 1);
continue;
}
}
else if (cur.has(until))
{
// we're done; have already applied
Invariants.checkState(depth == 0);
break;
}
TxnId directlyBlockedOnCommit = firstWaitingOnCommit(cur);
TxnId directlyBlockedOnApply = firstWaitingOnApply(cur, directlyBlockedOnCommit);
if (directlyBlockedOnApply != null)
{
push(directlyBlockedOnApply, Known.Done);
}
else if (directlyBlockedOnCommit != null)
{
push(directlyBlockedOnCommit, ExecuteAtOnly);
}
else
{
if (cur.hasBeen(Committed) && !cur.hasBeen(ReadyToExecute) && !cur.asCommitted().isWaitingOnDependency())
{
if (!maybeExecute(safeStore, curSafe, progressShard(safeStore, cur), false, false))
throw new AssertionError("Is able to Apply, but has not done so");
// loop and re-test the command's status; we may still want to notify blocking, esp. if not homeShard
continue;
}
Unseekables<?, ?> someKeys = cur.maxUnseekables();
if (someKeys == null && prev != null) someKeys = prev.partialDeps().someUnseekables(cur.txnId());
Invariants.checkState(someKeys != null);
logger.trace("{} blocked on {} until {}", txnIds[0], cur.txnId(), until);
safeStore.progressLog().waiting(cur.txnId(), until, someKeys);
return;
}
prevSafe = curSafe;
}
}