in accord-core/src/main/java/accord/local/Commands.java [312:375]
public static CommitOutcome commit(SafeCommandStore safeStore, SafeCommand safeCommand, StoreParticipants participants, SaveStatus newSaveStatus, Ballot ballot, TxnId txnId, Route<?> route, @Nullable Txn txn, Timestamp executeAt, Deps deps, @Nullable Commit.Kind kind)
{
final Command command = safeCommand.current();
if (kind == StableFastPath && !command.promised().equals(Ballot.ZERO))
return CommitOutcome.Rejected;
SaveStatus curStatus = command.saveStatus();
Invariants.requireArgument(newSaveStatus == SaveStatus.Committed || newSaveStatus == SaveStatus.Stable);
if (newSaveStatus == SaveStatus.Committed && ballot.compareTo(command.promised()) < 0)
return curStatus.is(Truncated) || participants.owns().isEmpty()
? CommitOutcome.Redundant : CommitOutcome.Rejected;
if (curStatus.hasBeen(PreCommitted))
{
if (!curStatus.is(Truncated))
{
if (!executeAt.equals(command.executeAt()) || curStatus.status == Invalidated)
safeStore.agent().onInconsistentTimestamp(command, (curStatus.status == Invalidated ? Timestamp.NONE : command.executeAt()), executeAt);
}
if (curStatus.compareTo(newSaveStatus) > 0 || curStatus.hasBeen(Stable))
{
logger.trace("{}: skipping commit - already newer or stable ({})", txnId, command.status());
return CommitOutcome.Redundant;
}
if (curStatus == SaveStatus.Committed && newSaveStatus == SaveStatus.Committed)
{
if (ballot.equals(command.acceptedOrCommitted()))
return CommitOutcome.Redundant;
Invariants.require(ballot.compareTo(command.acceptedOrCommitted()) > 0);
}
}
participants = participants.filter(UPDATE, safeStore, txnId, executeAt);
Validated validated = validate(ballot, newSaveStatus, command, participants, route, txn, deps, kind, executeAt);
if (validated == INSUFFICIENT)
return CommitOutcome.Insufficient;
PartialTxn partialTxn = prepareTxn(newSaveStatus, participants, command, txn);
PartialDeps partialDeps = prepareDeps(validated, participants, command, deps);
participants = prepareParticipants(validated, participants, command);
if (logger.isTraceEnabled())
logger.trace("{}: committed with executeAt: {}, deps: {}", txnId, executeAt, deps);
final Command.Committed committed;
if (newSaveStatus == SaveStatus.Stable)
{
WaitingOn waitingOn = initialiseWaitingOn(safeStore, txnId, executeAt, participants, partialDeps);
committed = safeCommand.stable(safeStore, participants, ballot, executeAt, partialTxn, partialDeps, waitingOn);
safeStore.agent().eventListener().onStable(committed);
maybeExecute(safeStore, safeCommand, true, true);
}
else
{
Invariants.requireArgument(command.acceptedOrCommitted().compareTo(ballot) <= 0);
committed = safeCommand.commit(safeStore, participants, ballot, executeAt, partialTxn, partialDeps);
safeStore.notifyListeners(safeCommand, committed);
safeStore.agent().eventListener().onCommitted(committed);
}
return CommitOutcome.Success;
}