This is an automated email from the ASF dual-hosted git repository.
dcapwell pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-accord.git
The following commit(s) were added to refs/heads/trunk by this push:
new f6b0a699 Updated so txn.execute is always called before txn.result,
which enables Cassandra to pass around rejections found while creating the
mutations.
f6b0a699 is described below
commit f6b0a6998faca767e6951976097dec704c306b0e
Author: David Capwell <[email protected]>
AuthorDate: Thu Dec 11 09:31:20 2025 -0800
Updated so txn.execute is always called before txn.result, which enables
Cassandra to pass around rejections found while creating the mutations.
patch by David Capwell; reviewed by Benedict Elliott Smith, Caleb
Rackliffe, Jyothsna Konisa for CASSANDRA-21061
---
.../main/java/accord/coordinate/ExecuteTxn.java | 7 ++---
.../src/main/java/accord/utils/RandomSource.java | 8 +++++
accord-core/src/test/java/accord/utils/Gens.java | 3 ++
.../src/test/java/accord/utils/Property.java | 36 +++++++++++++++-------
gradle.properties | 4 +++
gradle/wrapper/gradle-wrapper.properties | 3 +-
6 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/accord-core/src/main/java/accord/coordinate/ExecuteTxn.java
b/accord-core/src/main/java/accord/coordinate/ExecuteTxn.java
index 3c1e2a52..5b06000a 100644
--- a/accord-core/src/main/java/accord/coordinate/ExecuteTxn.java
+++ b/accord-core/src/main/java/accord/coordinate/ExecuteTxn.java
@@ -391,11 +391,10 @@ public class ExecuteTxn extends ReadCoordinator<Result,
ReadReply>
executeAt = new TimestampWithUniqueHlc(executeAt, uniqueHlc);
}
- // Always compute Result before Write to provide integrations with
a predictable invocation order
- // in case there is shared state between Result and Update. This
can change if really needed
- // just make sure to check the integrations to make sure it won't
break anything
- Result result = txn.result(txnId, executeAt, data);
+ // Always compute Writes before Result to provide integrations
with a predictable invocation order
+ // in case there is shared state between Result and Update.
Writes writes = txnId.is(Txn.Kind.Write) ? txn.execute(txnId,
executeAt, data) : null;
+ Result result = txn.result(txnId, executeAt, data);
adapter().persist(node, executor, allTopologies, route, ballot,
flags, txnId, txn, executeAt, stableDeps, writes, result, takeCallback());
}
else
diff --git a/accord-core/src/main/java/accord/utils/RandomSource.java
b/accord-core/src/main/java/accord/utils/RandomSource.java
index 80b3cd2f..c3decc5e 100644
--- a/accord-core/src/main/java/accord/utils/RandomSource.java
+++ b/accord-core/src/main/java/accord/utils/RandomSource.java
@@ -292,24 +292,32 @@ public interface RandomSource
default <T> T pickOrderedSet(SortedSet<T> set)
{
+ Invariants.require(!set.isEmpty(), "can not pick from an empty
collection");
+ if (set.size() == 1) return Iterables.getFirst(set, null);
int offset = nextInt(0, set.size());
return Iterables.get(set, offset);
}
default <T> T pickOrderedSet(LinkedHashSet<T> set)
{
+ Invariants.require(!set.isEmpty(), "can not pick from an empty
collection");
+ if (set.size() == 1) return Iterables.getFirst(set, null);
int offset = nextInt(0, set.size());
return Iterables.get(set, offset);
}
default <T extends Enum<T>> T pickOrderedSet(EnumSet<T> set)
{
+ Invariants.require(!set.isEmpty(), "can not pick from an empty
collection");
+ if (set.size() == 1) return Iterables.getFirst(set, null);
int offset = nextInt(0, set.size());
return Iterables.get(set, offset);
}
default <T extends Comparable<? super T>> T pickUnorderedSet(Set<T> set)
{
+ Invariants.require(!set.isEmpty(), "can not pick from an empty
collection");
+ if (set.size() == 1) return Iterables.getFirst(set, null);
if (set instanceof SortedSet)
return pickOrderedSet((SortedSet<T>) set);
List<T> values = new ArrayList<>(set);
diff --git a/accord-core/src/test/java/accord/utils/Gens.java
b/accord-core/src/test/java/accord/utils/Gens.java
index c310fb6b..5af02308 100644
--- a/accord-core/src/test/java/accord/utils/Gens.java
+++ b/accord-core/src/test/java/accord/utils/Gens.java
@@ -862,6 +862,9 @@ public class Gens
*/
public static <T> Gen<Gen<T>> mixedDistribution(List<T> list)
{
+ Invariants.require(!list.isEmpty(), "can not pick from an empty
collection");
+ if (list.size() == 1)
+ return i -> constant(list.get(0));
return rs -> {
switch (rs.nextInt(0, 4))
{
diff --git a/accord-core/src/test/java/accord/utils/Property.java
b/accord-core/src/test/java/accord/utils/Property.java
index 92faad08..0bd40f44 100644
--- a/accord-core/src/test/java/accord/utils/Property.java
+++ b/accord-core/src/test/java/accord/utils/Property.java
@@ -72,6 +72,11 @@ public class Property
}
@SuppressWarnings("unchecked")
+ public T withOnlySeed(long seed)
+ {
+ return withSeed(seed).withExamples(1);
+ }
+
public T withExamples(int examples)
{
if (examples <= 0)
@@ -104,7 +109,7 @@ public class Property
}
catch (ExecutionException e)
{
- throw new PropertyError(propertyError(this, e.getCause()));
+ throw new PropertyError(propertyError(this, e.getCause()),
e.getCause());
}
catch (InterruptedException e)
{
@@ -213,10 +218,11 @@ public class Property
return sb.toString();
}
- private static String statefulPropertyError(StatefulBuilder input,
Throwable cause, Object state, List<String> history)
+ private static String statefulPropertyError(StatefulBuilder input,
Throwable cause, Object state, int failingStep, List<String> history)
{
StringBuilder sb = propertyErrorCommon(input, cause);
sb.append("Steps: ").append(input.steps).append('\n');
+ sb.append("Failing Step: ").append(failingStep).append('\n');
sb.append("Values:\n");
String stateStr = state == null ? null :
state.toString().replace("\n", "\n\t\t");
sb.append("\tState: ").append(stateStr).append(": ").append(state ==
null ? "unknown type" : state.getClass().getCanonicalName()).append('\n');
@@ -493,6 +499,7 @@ public class Property
{
State state = null;
List<String> history = new ArrayList<>(steps);
+ int seenCommands = 0;
LongArrayList historyTiming = stepTimeout == null ? null : new
LongArrayList();
try
{
@@ -506,7 +513,7 @@ public class Property
for (int j = 0; j < steps; j++)
{
Gen<Command<State, SystemUnderTest, ?>> cmdGen =
commands.commands(state);
- Command cmd = cmdGen.next(rs);
+ Command<State, SystemUnderTest, ?> cmd =
cmdGen.next(rs);
for (int a = 0; cmd.checkPreconditions(state) !=
PreCheckResult.Ok && a < 42; a++)
{
if (a == 41)
@@ -517,14 +524,16 @@ public class Property
{
for (Command<State, SystemUnderTest, ?> sub :
((MultistepCommand<State, SystemUnderTest>) cmd))
{
+ seenCommands++;
history.add(sub.detailed(state));
- process(sub, state, sut, history.size(),
historyTiming);
+ process(sub, state, sut, seenCommands,
historyTiming);
}
}
else
{
+ seenCommands++;
history.add(cmd.detailed(state));
- process(cmd, state, sut, history.size(),
historyTiming);
+ process(cmd, state, sut, seenCommands,
historyTiming);
}
}
commands.destroySut(sut, null);
@@ -542,7 +551,7 @@ public class Property
}
catch (Throwable t)
{
- throw new PropertyError(statefulPropertyError(this, t,
state, maybeRewriteHistory(history, historyTiming)), t);
+ throw new PropertyError(statefulPropertyError(this, t,
state, seenCommands, maybeRewriteHistory(history, historyTiming)), t);
}
if (pure)
{
@@ -577,8 +586,7 @@ public class Property
return newHistory;
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private <State, SystemUnderTest> void process(Command cmd, State
state, SystemUnderTest sut, int id, @Nullable LongArrayList stepTiming) throws
Throwable
+ private <State, SystemUnderTest> void process(Command<State,
SystemUnderTest, ?> cmd, State state, SystemUnderTest sut, int id, @Nullable
LongArrayList stepTiming) throws Throwable
{
if (stepTimeout == null)
{
@@ -609,8 +617,10 @@ public class Property
default String detailed(State state) {return this.toString();}
default void process(State state, SystemUnderTest sut) throws Throwable
{
- checkPostconditions(state, apply(state),
- sut, run(sut));
+ Result apply = apply(state);
+ Result run = run(sut);
+ checkPostconditions(state, apply,
+ sut, run);
}
}
@@ -851,6 +861,7 @@ public class Property
default void destroyState(State state, @Nullable Throwable cause)
throws Throwable {}
default void destroySut(SystemUnderTest sut, @Nullable Throwable
cause) throws Throwable {}
Gen<Command<State, SystemUnderTest, ?>> commands(State state) throws
Throwable;
+
}
public static <State, SystemUnderTest> CommandsBuilder<State,
SystemUnderTest> commands(Supplier<Gen<State>> stateGen, Function<State,
SystemUnderTest> sutFactory)
@@ -907,6 +918,7 @@ public class Property
this.sutFactory = sutFactory;
}
+
public CommandsBuilder<State, SystemUnderTest>
preCommands(FailingConsumer<State> preCommands)
{
this.preCommands = preCommands;
@@ -1126,7 +1138,7 @@ public class Property
for (Setup<State, SystemUnderTest> s :
unknownWeights)
weights.put(s,
unknownWeightGen.nextInt(rs));
}
- nonConditional = Gens.pick(weights);
+ nonConditional = weights.isEmpty() ? null :
Gens.pick(weights);
if (conditionalCommands != null)
{
conditionalWeights = new LinkedHashMap<>();
@@ -1233,6 +1245,7 @@ public class Property
for (var fn : onFailures)
fn.onFailure(state, sut, history, cause);
}
+
};
}
@@ -1251,4 +1264,5 @@ public class Property
void accept(A a, B b) throws Throwable;
}
}
+
}
diff --git a/gradle.properties b/gradle.properties
index fa64f1f6..6057f461 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,3 +17,7 @@
accord_group=accord
accord_artifactId=accord
accord_version=1.0-SNAPSHOT
+
+# Some times there are ephemeral issues with fetching dependencies (namely
Rat) in CI, so this bumps the timeout to 120s to try to make it more stable
+systemProp.org.gradle.internal.http.connectionTimeout=120000
+systemProp.org.gradle.internal.http.socketTimeout=120000
diff --git a/gradle/wrapper/gradle-wrapper.properties
b/gradle/wrapper/gradle-wrapper.properties
index 72371299..8a9c3cdf 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -17,6 +17,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
-networkTimeout=10000
+# Some CI environments have ephemeral issues fetching the gradle runtime, so
increased the timeout from the default 10s to 60s to make it more stable
+networkTimeout=60000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]