2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.cluster.raft;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Stopwatch;
13 import java.util.concurrent.TimeUnit;
15 public class FollowerLogInformationImpl implements FollowerLogInformation {
16 private final Stopwatch stopwatch = Stopwatch.createUnstarted();
18 private final RaftActorContext context;
20 private long nextIndex;
22 private long matchIndex;
24 private long lastReplicatedIndex = -1L;
26 private final Stopwatch lastReplicatedStopwatch = Stopwatch.createUnstarted();
28 private short payloadVersion = -1;
30 private final PeerInfo peerInfo;
32 public FollowerLogInformationImpl(PeerInfo peerInfo, long matchIndex, RaftActorContext context) {
33 this.nextIndex = context.getCommitIndex();
34 this.matchIndex = matchIndex;
35 this.context = context;
36 this.peerInfo = Preconditions.checkNotNull(peerInfo);
40 public long incrNextIndex() {
45 public long decrNextIndex() {
50 public boolean setNextIndex(long nextIndex) {
51 if(this.nextIndex != nextIndex) {
52 this.nextIndex = nextIndex;
60 public long incrMatchIndex(){
65 public boolean setMatchIndex(long matchIndex) {
66 if(this.matchIndex != matchIndex) {
67 this.matchIndex = matchIndex;
75 public String getId() {
76 return peerInfo.getId();
80 public long getNextIndex() {
85 public long getMatchIndex() {
90 public boolean isFollowerActive() {
91 if(peerInfo.getVotingState() == VotingState.VOTING_NOT_INITIALIZED) {
95 long elapsed = stopwatch.elapsed(TimeUnit.MILLISECONDS);
96 return (stopwatch.isRunning()) &&
97 (elapsed <= context.getConfigParams().getElectionTimeOutInterval().toMillis());
101 public void markFollowerActive() {
102 if (stopwatch.isRunning()) {
109 public void markFollowerInActive() {
110 if (stopwatch.isRunning()) {
116 public long timeSinceLastActivity() {
117 return stopwatch.elapsed(TimeUnit.MILLISECONDS);
121 public boolean okToReplicate() {
122 if(peerInfo.getVotingState() == VotingState.VOTING_NOT_INITIALIZED) {
126 // Return false if we are trying to send duplicate data before the heartbeat interval
127 if(getNextIndex() == lastReplicatedIndex){
128 if(lastReplicatedStopwatch.elapsed(TimeUnit.MILLISECONDS) < context.getConfigParams()
129 .getHeartBeatInterval().toMillis()){
134 resetLastReplicated();
138 private void resetLastReplicated(){
139 lastReplicatedIndex = getNextIndex();
140 if(lastReplicatedStopwatch.isRunning()){
141 lastReplicatedStopwatch.reset();
143 lastReplicatedStopwatch.start();
147 public short getPayloadVersion() {
148 return payloadVersion;
152 public void setPayloadVersion(short payloadVersion) {
153 this.payloadVersion = payloadVersion;
157 public String toString() {
158 return "FollowerLogInformationImpl [id=" + getId() + ", nextIndex=" + nextIndex + ", matchIndex=" + matchIndex
159 + ", lastReplicatedIndex=" + lastReplicatedIndex + ", votingState=" + peerInfo.getVotingState()
160 + ", stopwatch=" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + ", followerTimeoutMillis="
161 + context.getConfigParams().getElectionTimeOutInterval().toMillis() + "]";