This is an automated email from the ASF dual-hosted git repository. benedict pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra-accord.git
commit da4450e61bbaf59cf7a3b254f1f304e0c2bb9f7f Author: Benedict Elliott Smith <bened...@apache.org> AuthorDate: Mon Jan 22 20:16:31 2024 +0000 fixes --- .../src/main/java/accord/local/Bootstrap.java | 4 +-- .../src/main/java/accord/local/Command.java | 30 +++++++++++----------- .../src/main/java/accord/local/Commands.java | 8 +++--- .../src/main/java/accord/local/SaveStatus.java | 22 ++++++++-------- accord-core/src/main/java/accord/local/Status.java | 13 +++++++--- 5 files changed, 41 insertions(+), 36 deletions(-) diff --git a/accord-core/src/main/java/accord/local/Bootstrap.java b/accord-core/src/main/java/accord/local/Bootstrap.java index 6423fe2..3521fff 100644 --- a/accord-core/src/main/java/accord/local/Bootstrap.java +++ b/accord-core/src/main/java/accord/local/Bootstrap.java @@ -134,13 +134,13 @@ class Bootstrap Ranges commitRanges = valid; store.markBootstrapping(safeStore0, globalSyncId, valid); CoordinateSyncPoint.exclusive(node, globalSyncId, commitRanges) - // TODO (correcness) : PreLoadContext only works with Seekables, which doesn't allow mixing Keys and Ranges... But Deps has both Keys AND Ranges! + // TODO (required, correcness) : PreLoadContext only works with Seekables, which doesn't allow mixing Keys and Ranges... But Deps has both Keys AND Ranges! // ATM all known implementations store ranges in-memory, but this will not be true soon, so this will need to be addressed .flatMap(syncPoint -> node.withEpoch(epoch, () -> store.submit(contextFor(localSyncId, syncPoint.waitFor.keyDeps.keys(), KeyHistory.DEPS), safeStore1 -> { if (valid.isEmpty()) // we've lost ownership of the range return AsyncResults.success(Ranges.EMPTY); - Commands.commitRecipientLocalSyncPoint(safeStore1, localSyncId, syncPoint, valid); + Commands.stableRecipientLocalSyncPoint(safeStore1, localSyncId, syncPoint, valid); safeStore1.registerHistoricalTransactions(syncPoint.waitFor); return fetch = safeStore1.dataStore().fetch(node, safeStore1, valid, syncPoint, this); }))) diff --git a/accord-core/src/main/java/accord/local/Command.java b/accord-core/src/main/java/accord/local/Command.java index 7c287aa..9665f4c 100644 --- a/accord-core/src/main/java/accord/local/Command.java +++ b/accord-core/src/main/java/accord/local/Command.java @@ -352,8 +352,11 @@ public abstract class Command implements CommonAttributes switch (known.executeAt) { default: throw new AssertionError("Unhandled KnownExecuteAt: " + known.executeAt); + case ExecuteAtNotWitnessed: + Invariants.checkState(executeAt == null); case ExecuteAtErased: - case ExecuteAtUnknown: break; + case ExecuteAtUnknown: + break; case ExecuteAtProposed: case ExecuteAtKnown: Invariants.checkState(executeAt != null && !executeAt.equals(Timestamp.NONE)); @@ -575,9 +578,7 @@ public abstract class Command implements CommonAttributes { if (status().hasBeen(Status.Truncated)) return false; - boolean result = status().hasBeen(Status.PreAccepted); - Invariants.checkState(result == (this instanceof PreAccepted), "Unexpected type: %s, %s", this, this.getClass().getCanonicalName()); - return result; + return status().hasBeen(Status.PreAccepted); } public final PreAccepted asWitnessed() @@ -587,9 +588,7 @@ public abstract class Command implements CommonAttributes public final boolean isAccepted() { - boolean result = status().hasBeen(Status.AcceptedInvalidate); - Invariants.checkState(result == (this instanceof Accepted), "Unexpected type: %s, %s", this, this.getClass().getCanonicalName()); - return result; + return status().hasBeen(Status.AcceptedInvalidate); } public final Accepted asAccepted() @@ -599,9 +598,13 @@ public abstract class Command implements CommonAttributes public final boolean isCommitted() { - boolean result = status().hasBeen(Status.Committed); - Invariants.checkState(result == (this instanceof Committed), "Unexpected type: %s, %s", this, this.getClass().getCanonicalName()); - return result; + SaveStatus saveStatus = saveStatus(); + return saveStatus.hasBeen(Status.Committed) && !saveStatus.hasBeen(Invalidated); + } + public final boolean isStable() + { + SaveStatus saveStatus = saveStatus(); + return saveStatus.hasBeen(Status.Stable) && !saveStatus.hasBeen(Invalidated); } public final Committed asCommitted() @@ -616,9 +619,7 @@ public abstract class Command implements CommonAttributes public final boolean isTruncated() { - boolean result = status().hasBeen(Status.Truncated); - Invariants.checkState(result == (this instanceof Truncated), "Unexpected type: %s, %s", this, this.getClass().getCanonicalName()); - return result; + return status().hasBeen(Status.Truncated); } public abstract Command updateAttributes(CommonAttributes attrs, Ballot promised); @@ -1586,8 +1587,7 @@ public abstract class Command implements CommonAttributes static Command.Accepted acceptInvalidated(Command command, Ballot ballot) { - Timestamp executeAt = command.isDefined() ? command.asWitnessed().executeAt() : null; - return validate(new Command.Accepted(command, SaveStatus.get(Status.AcceptedInvalidate, command.known()), ballot, executeAt, command.partialTxn(), null, ballot)); + return validate(new Command.Accepted(command, SaveStatus.get(Status.AcceptedInvalidate, command.known()), ballot, command.executeAt(), command.partialTxn(), null, ballot)); } static Command.Committed commit(Command command, CommonAttributes attrs, Ballot ballot, Timestamp executeAt) diff --git a/accord-core/src/main/java/accord/local/Commands.java b/accord-core/src/main/java/accord/local/Commands.java index 0adde95..abb5dc7 100644 --- a/accord-core/src/main/java/accord/local/Commands.java +++ b/accord-core/src/main/java/accord/local/Commands.java @@ -403,19 +403,19 @@ public class Commands return CommitOutcome.Success; } - public static void commitRecipientLocalSyncPoint(SafeCommandStore safeStore, TxnId localSyncId, SyncPoint syncPoint, Seekables<?, ?> keys) + public static void stableRecipientLocalSyncPoint(SafeCommandStore safeStore, TxnId localSyncId, SyncPoint syncPoint, Seekables<?, ?> keys) { SafeCommand safeCommand = safeStore.get(localSyncId); Command command = safeCommand.current(); Invariants.checkState(!command.hasBeen(Committed)); - commitRecipientLocalSyncPoint(safeStore, localSyncId, keys, syncPoint.route()); + stableRecipientLocalSyncPoint(safeStore, localSyncId, keys, syncPoint.route()); } - private static void commitRecipientLocalSyncPoint(SafeCommandStore safeStore, TxnId localSyncId, Seekables<?, ?> keys, Route<?> route) + private static void stableRecipientLocalSyncPoint(SafeCommandStore safeStore, TxnId localSyncId, Seekables<?, ?> keys, Route<?> route) { SafeCommand safeCommand = safeStore.get(localSyncId); Command command = safeCommand.current(); - if (command.hasBeen(Committed)) + if (command.hasBeen(Stable)) return; Ranges coordinateRanges = coordinateRanges(safeStore, localSyncId); diff --git a/accord-core/src/main/java/accord/local/SaveStatus.java b/accord-core/src/main/java/accord/local/SaveStatus.java index 3ac810a..2005e12 100644 --- a/accord-core/src/main/java/accord/local/SaveStatus.java +++ b/accord-core/src/main/java/accord/local/SaveStatus.java @@ -60,13 +60,13 @@ public enum SaveStatus // This means voters recovering an earlier transaction will not consider the record when excluding the possibility of a fast-path commit. // This is safe, because any Accept that may override the AcceptedInvalidate will construct new Deps that must now witness the recovering transaction. AcceptedInvalidate (Status.AcceptedInvalidate), - AcceptedInvalidateWithDefinition(Status.AcceptedInvalidate, Full, DefinitionKnown, ExecuteAtUnknown, DepsUnknown, Unknown), + AcceptedInvalidateWithDefinition(Status.AcceptedInvalidate, Full, DefinitionKnown, ExecuteAtUnknown, DepsUnknown, Unknown), Accepted (Status.Accepted), - AcceptedWithDefinition (Status.Accepted, Full, DefinitionKnown, ExecuteAtProposed, DepsProposed, Unknown), + AcceptedWithDefinition (Status.Accepted, Full, DefinitionKnown, ExecuteAtProposed, DepsProposed, Unknown), PreCommitted (Status.PreCommitted, LocalExecution.ReadyToExclude), - PreCommittedWithAcceptedDeps (Status.PreCommitted, Covering, DefinitionUnknown, ExecuteAtKnown, DepsProposed, Unknown, LocalExecution.ReadyToExclude), - PreCommittedWithDefinition (Status.PreCommitted, Full, DefinitionKnown, ExecuteAtKnown, DepsUnknown, Unknown, LocalExecution.ReadyToExclude), - PreCommittedWithDefinitionAndAcceptedDeps(Status.PreCommitted, Full, DefinitionKnown, ExecuteAtKnown, DepsProposed, Unknown, LocalExecution.ReadyToExclude), + PreCommittedWithAcceptedDeps (Status.PreCommitted, Covering, DefinitionUnknown, ExecuteAtKnown, DepsProposed, Unknown, LocalExecution.ReadyToExclude), + PreCommittedWithDefinition (Status.PreCommitted, Full, DefinitionKnown, ExecuteAtKnown, DepsUnknown, Unknown, LocalExecution.ReadyToExclude), + PreCommittedWithDefinitionAndAcceptedDeps(Status.PreCommitted, Full, DefinitionKnown, ExecuteAtKnown, DepsProposed, Unknown, LocalExecution.ReadyToExclude), Committed (Status.Committed, LocalExecution.WaitingToExecute), Stable (Status.Stable, LocalExecution.WaitingToExecute), ReadyToExecute (Status.ReadyToExecute, LocalExecution.ReadyToExecute), @@ -76,14 +76,14 @@ public enum SaveStatus Applied (Status.Applied, LocalExecution.Applied), // TruncatedApplyWithDeps is a state never adopted within a single replica; it is however a useful state we may enter by combining state from multiple replicas // TODO (expected): TruncatedApplyWithDeps should be redundant now we have migrated away from SaveStatus in CheckStatusOk to Known; remove in isolated commit once stable - TruncatedApplyWithDeps (Status.Truncated, Full, DefinitionErased, ExecuteAtKnown, DepsKnown, Outcome.Apply, CleaningUp), - TruncatedApplyWithOutcome (Status.Truncated, Full, DefinitionErased, ExecuteAtKnown, DepsErased, Outcome.Apply, CleaningUp), - TruncatedApply (Status.Truncated, Full, DefinitionErased, ExecuteAtKnown, DepsErased, Outcome.WasApply, CleaningUp), + TruncatedApplyWithDeps (Status.Truncated, Full, DefinitionErased, ExecuteAtKnown, DepsKnown, Outcome.Apply, CleaningUp), + TruncatedApplyWithOutcome (Status.Truncated, Full, DefinitionErased, ExecuteAtKnown, DepsErased, Outcome.Apply, CleaningUp), + TruncatedApply (Status.Truncated, Full, DefinitionErased, ExecuteAtKnown, DepsErased, Outcome.WasApply, CleaningUp), // ErasedOrInvalidated means the command is redundant for the shard and data being queried, but no FullRoute is known, so it is not known to be globally Erased - ErasedOrInvalidated (Status.Truncated, Maybe, DefinitionUnknown,ExecuteAtUnknown, DepsUnknown, Unknown, CleaningUp), + ErasedOrInvalidated (Status.Truncated, Maybe, DefinitionUnknown, ExecuteAtUnknown, DepsUnknown, Unknown, CleaningUp), // NOTE: Erased should ONLY be adopted on a replica that knows EVERY shard has successfully applied the transaction at all healthy replicas. - Erased (Status.Truncated, Maybe, DefinitionErased, ExecuteAtErased, DepsErased, Outcome.Erased, CleaningUp), - Invalidated (Status.Invalidated, CleaningUp), + Erased (Status.Truncated, Maybe, DefinitionErased, ExecuteAtErased, DepsErased, Outcome.Erased, CleaningUp), + Invalidated (Status.Invalidated, CleaningUp), ; /** diff --git a/accord-core/src/main/java/accord/local/Status.java b/accord-core/src/main/java/accord/local/Status.java index b2dd8fa..bb44255 100644 --- a/accord-core/src/main/java/accord/local/Status.java +++ b/accord-core/src/main/java/accord/local/Status.java @@ -47,8 +47,8 @@ public enum Status { NotDefined (None, Nothing), PreAccepted (PreAccept, DefinitionAndRoute), - AcceptedInvalidate(Accept, Maybe, DefinitionUnknown, ExecuteAtUnknown, DepsUnknown, Unknown), // may or may not have witnessed - Accepted (Accept, Covering, DefinitionUnknown, ExecuteAtProposed, DepsProposed, Unknown), // may or may not have witnessed + AcceptedInvalidate(Accept, Maybe, DefinitionUnknown, ExecuteAtNotWitnessed, DepsUnknown, Unknown), // may or may not have witnessed + Accepted (Accept, Covering, DefinitionUnknown, ExecuteAtProposed, DepsProposed, Unknown), // may or may not have witnessed /** * PreCommitted is a peculiar state, half-way between Accepted and Committed. @@ -77,7 +77,7 @@ public enum Status */ PreCommitted (Accept, Maybe, DefinitionUnknown, ExecuteAtKnown, DepsUnknown, Unknown), - Committed (Commit, Full, DefinitionKnown, ExecuteAtKnown, DepsCommitted, Unknown), + Committed (Commit, Full, DefinitionKnown, ExecuteAtKnown, DepsCommitted, Unknown), Stable (Execute, Full, DefinitionKnown, ExecuteAtKnown, DepsKnown, Unknown), // TODO (expected): do we need ReadyToExecute here, or can we keep it to SaveStatus only? ReadyToExecute (Execute, Full, DefinitionKnown, ExecuteAtKnown, DepsKnown, Unknown), @@ -124,7 +124,7 @@ public enum Status */ public static class Known { - public static final Known Nothing = new Known(Maybe, DefinitionUnknown, ExecuteAtUnknown, DepsUnknown, Unknown); + public static final Known Nothing = new Known(Maybe, DefinitionUnknown, ExecuteAtNotWitnessed, DepsUnknown, Unknown); // TODO (expected): deprecate DefinitionOnly public static final Known DefinitionOnly = new Known(Maybe, DefinitionKnown, ExecuteAtUnknown, DepsUnknown, Unknown); public static final Known DefinitionAndRoute = new Known(Full, DefinitionKnown, ExecuteAtUnknown, DepsUnknown, Unknown); @@ -465,6 +465,11 @@ public enum Status public enum KnownExecuteAt { + /** + * No decision is known to have been reached. The transaction has not been witnessed so executeAt is null. + */ + ExecuteAtNotWitnessed, + /** * No decision is known to have been reached. If executeAt is not null, it represents either when * the transaction was witnessed, or some earlier ExecuteAtProposed that was invalidated by AcceptedInvalidate --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org