Skip to content

Commit 47f2bb5

Browse files
authored
Remove last accepted slot (elastic#10)
Relates to elastic/elasticsearch-formal-models#21
1 parent 158cbee commit 47f2bb5

File tree

3 files changed

+70
-36
lines changed

3 files changed

+70
-36
lines changed

core/src/main/java/org/elasticsearch/discovery/zen2/ConsensusState.java

+61-16
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.elasticsearch.discovery.zen2.Messages.ApplyCommit;
2626
import org.elasticsearch.discovery.zen2.Messages.PublishRequest;
2727
import org.elasticsearch.discovery.zen2.Messages.PublishResponse;
28-
import org.elasticsearch.discovery.zen2.Messages.SlotTermDiff;
2928
import org.elasticsearch.discovery.zen2.Messages.Vote;
3029

3130
import java.util.HashMap;
@@ -48,15 +47,15 @@ public class ConsensusState<T extends ConsensusState.CommittedState> extends Abs
4847
// persisted state
4948
private long currentTerm;
5049
private T committedState;
51-
private Optional<SlotTermDiff<T>> acceptedState;
50+
private Optional<AcceptedState<T>> acceptedState;
5251
// transient state
5352
private boolean electionWon;
5453
private boolean electionValueForced;
5554
private NodeCollection joinVotes;
5655
private boolean publishPermitted;
5756
private NodeCollection publishVotes;
5857

59-
public ConsensusState(Settings settings, long currentTerm, T committedState, Optional<SlotTermDiff<T>> acceptedState,
58+
public ConsensusState(Settings settings, long currentTerm, T committedState, Optional<AcceptedState<T>> acceptedState,
6059
Persistence<T> persistence) {
6160
// TODO idea: just pass in a Persistence and let it provide the persisted state.
6261

@@ -76,8 +75,7 @@ public ConsensusState(Settings settings, long currentTerm, T committedState, Opt
7675
this.publishVotes = new NodeCollection();
7776

7877
assert currentTerm >= 0;
79-
assert acceptedState.isPresent() == false || acceptedState.get().getTerm() <= currentTerm;
80-
assert acceptedState.isPresent() == false || acceptedState.get().getSlot() <= firstUncommittedSlot();
78+
assert lastAcceptedTerm() <= currentTerm;
8179
}
8280

8381
public T getCommittedState() {
@@ -98,8 +96,8 @@ public long firstUncommittedSlot() {
9896
return committedState.getSlot() + 1;
9997
}
10098

101-
public long lastAcceptedTermInSlot() {
102-
if (acceptedState.isPresent() && firstUncommittedSlot() == acceptedState.get().getSlot()) {
99+
public long lastAcceptedTerm() {
100+
if (acceptedState.isPresent()) {
103101
return acceptedState.get().getTerm();
104102
} else {
105103
return NO_TERM;
@@ -131,7 +129,7 @@ public Vote handleStartVote(long newTerm) {
131129
publishPermitted = true;
132130
publishVotes = new NodeCollection();
133131

134-
return new Vote(firstUncommittedSlot(), currentTerm, lastAcceptedTermInSlot());
132+
return new Vote(firstUncommittedSlot(), currentTerm, lastAcceptedTerm());
135133
}
136134

137135
/**
@@ -155,7 +153,7 @@ public Optional<PublishRequest<T>> handleVote(DiscoveryNode sourceNode, Vote vot
155153
firstUncommittedSlot());
156154
}
157155
if (vote.getFirstUncommittedSlot() == firstUncommittedSlot() && vote.getLastAcceptedTerm() != NO_TERM) {
158-
final long lastAcceptedTermInSlot = lastAcceptedTermInSlot();
156+
final long lastAcceptedTermInSlot = lastAcceptedTerm();
159157
if (vote.getLastAcceptedTerm() > lastAcceptedTermInSlot) {
160158
logger.debug("handleVote: ignored vote as voter has better last accepted term (expected: <=[{}], actual: [{}])",
161159
lastAcceptedTermInSlot, vote.getLastAcceptedTerm());
@@ -212,8 +210,9 @@ public PublishResponse handlePublishRequest(PublishRequest<T> publishRequest) {
212210

213211
logger.trace("handlePublishRequest: storing publish request for slot [{}] and term [{}]",
214212
publishRequest.getSlot(), publishRequest.getTerm());
215-
persistence.persistAcceptedState(publishRequest);
216-
acceptedState = Optional.of(publishRequest);
213+
final AcceptedState<T> termDiff = publishRequest.getAcceptedState();
214+
persistence.persistAcceptedState(termDiff);
215+
acceptedState = Optional.of(termDiff);
217216

218217
return new PublishResponse(publishRequest.getSlot(), publishRequest.getTerm());
219218
}
@@ -264,11 +263,11 @@ public Optional<ApplyCommit> handlePublishResponse(DiscoveryNode sourceNode, Pub
264263
* @throws IllegalArgumentException if the arguments were incompatible with the current state of this object.
265264
*/
266265
public void handleCommit(ApplyCommit applyCommit) {
267-
if (applyCommit.getTerm() != lastAcceptedTermInSlot()) {
266+
if (applyCommit.getTerm() != lastAcceptedTerm()) {
268267
logger.debug("handleCommit: ignored commit request due to term mismatch (expected: [{}], actual: [{}])",
269-
lastAcceptedTermInSlot(), applyCommit.getTerm());
268+
lastAcceptedTerm(), applyCommit.getTerm());
270269
throw new IllegalArgumentException("incoming term " + applyCommit.getTerm() + " does not match last accepted term " +
271-
lastAcceptedTermInSlot());
270+
lastAcceptedTerm());
272271
}
273272
if (applyCommit.getSlot() != firstUncommittedSlot()) {
274273
logger.debug("handleCommit: ignored commit request due to slot mismatch (expected: [{}], actual: [{}])",
@@ -280,13 +279,13 @@ public void handleCommit(ApplyCommit applyCommit) {
280279
logger.trace("handleCommit: applying commit request for slot [{}]", applyCommit.getSlot());
281280

282281
assert acceptedState.isPresent();
283-
assert acceptedState.get().getSlot() == committedState.getSlot() + 1;
284282
final T newCommittedState = acceptedState.get().getDiff().apply(committedState);
285283
logger.trace("handleCommit: newCommittedState = [{}]", newCommittedState);
286284
assert newCommittedState.getSlot() == committedState.getSlot() + 1;
287285

288286
persistence.persistCommittedState(newCommittedState);
289287
committedState = newCommittedState;
288+
acceptedState = Optional.empty();
290289
publishPermitted = true;
291290
electionValueForced = false;
292291
publishVotes = new NodeCollection();
@@ -318,6 +317,7 @@ public void applyCatchup(T newCommittedState) {
318317
logger.debug("applyCatchup: applying catch up for slot [{}]", newCommittedState.getSlot());
319318
persistence.persistCommittedState(newCommittedState);
320319
committedState = newCommittedState;
320+
acceptedState = Optional.empty();
321321
electionValueForced = false;
322322
joinVotes = new NodeCollection();
323323
electionWon = false;
@@ -360,12 +360,57 @@ public interface CommittedState {
360360
NodeCollection getVotingNodes();
361361
}
362362

363+
public static class AcceptedState<T> {
364+
protected final long term;
365+
protected final Diff<T> diff;
366+
367+
public AcceptedState(long term, Diff<T> diff) {
368+
this.term = term;
369+
this.diff = diff;
370+
}
371+
372+
public long getTerm() {
373+
return term;
374+
}
375+
376+
public Diff<T> getDiff() {
377+
return diff;
378+
}
379+
380+
@Override
381+
public boolean equals(Object o) {
382+
if (this == o) return true;
383+
if (o == null || getClass() != o.getClass()) return false;
384+
385+
AcceptedState<?> termDiff = (AcceptedState<?>) o;
386+
387+
if (term != termDiff.term) return false;
388+
return diff.equals(termDiff.diff);
389+
}
390+
391+
@Override
392+
public int hashCode() {
393+
int result = (int) (term ^ (term >>> 32));
394+
result = 31 * result + diff.hashCode();
395+
return result;
396+
}
397+
398+
399+
@Override
400+
public String toString() {
401+
return "AcceptedState{" +
402+
"term=" + term +
403+
", diff=" + diff +
404+
'}';
405+
}
406+
}
407+
363408
public interface Persistence<T> {
364409
void persistCurrentTerm(long currentTerm);
365410

366411
void persistCommittedState(T committedState);
367412

368-
void persistAcceptedState(SlotTermDiff<T> slotTermDiff);
413+
void persistAcceptedState(AcceptedState<T> termDiff);
369414
}
370415

371416
/**

core/src/main/java/org/elasticsearch/discovery/zen2/Messages.java

+8-19
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ public String toString() {
159159
}
160160
}
161161

162-
public abstract static class SlotTermDiff<T> extends SlotTerm {
162+
public static class PublishRequest<T> extends SlotTerm {
163+
163164
protected final Diff<T> diff;
164165

165-
public SlotTermDiff(long slot, long term, Diff<T> diff) {
166+
public PublishRequest(long slot, long term, Diff<T> diff) {
166167
super(slot, term);
167168
this.diff = diff;
168169
}
@@ -171,12 +172,16 @@ public Diff<T> getDiff() {
171172
return diff;
172173
}
173174

175+
public ConsensusState.AcceptedState<T> getAcceptedState() {
176+
return new ConsensusState.AcceptedState<>(term, diff);
177+
}
178+
174179
@Override
175180
public boolean equals(Object o) {
176181
if (super.equals(o) == false) {
177182
return false;
178183
}
179-
SlotTermDiff<?> that = (SlotTermDiff<?>) o;
184+
PublishRequest<?> that = (PublishRequest<?>) o;
180185
return diff != null ? diff.equals(that.diff) : that.diff == null;
181186
}
182187

@@ -187,22 +192,6 @@ public int hashCode() {
187192
return result;
188193
}
189194

190-
@Override
191-
public String toString() {
192-
return "SlotTermDiff{" +
193-
"slot=" + slot +
194-
", term=" + term +
195-
", diff=" + diff +
196-
'}';
197-
}
198-
}
199-
200-
public static class PublishRequest<T> extends SlotTermDiff<T> {
201-
202-
public PublishRequest(long slot, long term, Diff<T> diff) {
203-
super(slot, term, diff);
204-
}
205-
206195
@Override
207196
public String toString() {
208197
return "PublishRequest{" +

core/src/test/java/org/elasticsearch/discovery/zen2/ConsensusStateTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void persistCommittedState(ClusterState committedState) {
5555
}
5656

5757
@Override
58-
public void persistAcceptedState(Messages.SlotTermDiff<ClusterState> slotTermDiff) {
58+
public void persistAcceptedState(ConsensusState.AcceptedState<ClusterState> termDiff) {
5959

6060
}
6161
});

0 commit comments

Comments
 (0)