jmckenzie-dev commented on code in PR #4030: URL: https://github.com/apache/cassandra/pull/4030#discussion_r2025511217
########## src/java/org/apache/cassandra/service/paxos/v1/PrepareCallback.java: ########## @@ -40,30 +41,43 @@ public class PrepareCallback extends AbstractPaxosCallback<PrepareResponse> { private static final Logger logger = LoggerFactory.getLogger(PrepareCallback.class); - public boolean promised = true; - public Commit mostRecentCommit; - public Commit mostRecentInProgressCommit; + private boolean promised = true; + private Commit mostRecentCommit; + private Commit mostRecentInProgressCommit; private final Map<InetAddressAndPort, Commit> commitsByReplica = new ConcurrentHashMap<>(); - public PrepareCallback(DecoratedKey key, TableMetadata metadata, int targets, ConsistencyLevel consistency, Dispatcher.RequestTime requestTime) + + public PrepareCallback(DecoratedKey key, TableMetadata metadata, ReplicaPlan.ForPaxosWrite replicaPlan, Dispatcher.RequestTime requestTime) { - super(targets, consistency, requestTime); + super(replicaPlan.contacts().endpoints(), replicaPlan.requiredParticipants(), replicaPlan.consistencyLevel(), requestTime); // need to inject the right key in the empty commit so comparing with empty commits in the response works as expected mostRecentCommit = Commit.emptyCommit(key, metadata); mostRecentInProgressCommit = Commit.emptyCommit(key, metadata); } - public synchronized void onResponse(Message<PrepareResponse> message) + public boolean isPromised() { return promised; } + public Commit getMostRecentCommit() { return mostRecentCommit; } + public Commit getMostRecentInProgressCommit() { return mostRecentInProgressCommit; } + + public synchronized void onResponse(Message<PrepareResponse> msg) { - PrepareResponse response = message.payload; - logger.trace("Prepare response {} from {}", response, message.from()); + Preconditions.checkNotNull(msg, "Got unexpected null message in onResponse callback."); + PrepareResponse response = msg.payload; + tracker.recordResponse(msg.from()); + logger.trace("Prepare response {} from {}", response, msg.from()); + + // We don't want to flip the promise state if we've already succeeded or failed on this callback; if we've hit + // a quorum promised subsequent failures shouldn't be considered in our calculation. + if (latch.count() == 0) + return; // We set the mostRecentInProgressCommit even if we're not promised as, in that case, the ballot of that commit // will be used to avoid generating a ballot that has not chance to win on retry (think clock skew). if (response.inProgressCommit.isAfter(mostRecentInProgressCommit)) mostRecentInProgressCommit = response.inProgressCommit; + // Immediately bail out if any participant declines if (!response.promised) { promised = false; Review Comment: ! Why yes. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: pr-unsubscr...@cassandra.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: pr-unsubscr...@cassandra.apache.org For additional commands, e-mail: pr-h...@cassandra.apache.org