import akka.actor.ActorSelection;
import akka.actor.ActorSystem;
import akka.actor.Props;
-
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Supplier;
+import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.LongSupplier;
import org.opendaylight.controller.cluster.DataPersistenceProvider;
-import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
import org.opendaylight.controller.cluster.raft.ServerConfigurationPayload.ServerInfo;
+import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
+import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
import org.slf4j.Logger;
public class RaftActorContextImpl implements RaftActorContext {
+ private static final LongSupplier JVM_MEMORY_RETRIEVER = () -> Runtime.getRuntime().maxMemory();
private final ActorRef actor;
private boolean dynamicServerConfiguration = false;
@VisibleForTesting
- private Supplier<Long> totalMemoryRetriever;
+ private LongSupplier totalMemoryRetriever = JVM_MEMORY_RETRIEVER;
// Snapshot manager will need to be created on demand as it needs raft actor context which cannot
// be passed to it in the constructor
private short payloadVersion;
+ private boolean votingMember = true;
+
+ private RaftActorBehavior currentBehavior;
+
public RaftActorContextImpl(ActorRef actor, ActorContext context, String id,
ElectionTerm termInformation, long commitIndex, long lastApplied, Map<String, String> peerAddresses,
ConfigParams configParams, DataPersistenceProvider persistenceProvider, Logger logger) {
}
}
+ @VisibleForTesting
public void setPayloadVersion(short payloadVersion) {
this.payloadVersion = payloadVersion;
}
peerAddress = configParams.getPeerAddressResolver().resolve(peerId);
peerInfo.setAddress(peerAddress);
}
+ } else {
+ peerAddress = configParams.getPeerAddressResolver().resolve(peerId);
}
return peerAddress;
@Override
public void updatePeerIds(ServerConfigurationPayload serverConfig){
-
+ votingMember = true;
+ boolean foundSelf = false;
Set<String> currentPeers = new HashSet<>(this.getPeerIds());
for(ServerInfo server: serverConfig.getServerConfig()) {
- if(!getId().equals(server.getId())) {
+ if(getId().equals(server.getId())) {
+ foundSelf = true;
+ if(!server.isVoting()) {
+ votingMember = false;
+ }
+ } else {
VotingState votingState = server.isVoting() ? VotingState.VOTING: VotingState.NON_VOTING;
if(!currentPeers.contains(server.getId())) {
this.addToPeers(server.getId(), null, votingState);
for(String peerIdToRemove: currentPeers) {
this.removePeer(peerIdToRemove);
}
+
+ if(!foundSelf) {
+ votingMember = false;
+ }
+
setDynamicServerConfigurationInUse();
}
peerInfoMap.put(id, new PeerInfo(id, address, votingState));
}
- @Override public void removePeer(String name) {
- peerInfoMap.remove(name);
+ @Override
+ public void removePeer(String name) {
+ if(getId().equals(name)) {
+ votingMember = false;
+ } else {
+ peerInfoMap.remove(name);
+ }
}
@Override public ActorSelection getPeerActorSelection(String peerId) {
@Override
public long getTotalMemory() {
- return totalMemoryRetriever != null ? totalMemoryRetriever.get() : Runtime.getRuntime().totalMemory();
+ return totalMemoryRetriever.getAsLong();
}
@Override
- public void setTotalMemoryRetriever(Supplier<Long> retriever) {
- totalMemoryRetriever = retriever;
+ public void setTotalMemoryRetriever(LongSupplier retriever) {
+ totalMemoryRetriever = retriever == null ? JVM_MEMORY_RETRIEVER : retriever;
}
@Override
}
@Override
- public ServerConfigurationPayload getPeerServerInfo() {
+ public ServerConfigurationPayload getPeerServerInfo(boolean includeSelf) {
if (!isDynamicServerConfigurationInUse()) {
return null;
}
newConfig.add(new ServerInfo(peer.getId(), peer.isVoting()));
}
- newConfig.add(new ServerInfo(getId(), true));
+ if(includeSelf) {
+ newConfig.add(new ServerInfo(getId(), votingMember));
+ }
+
return (new ServerConfigurationPayload(newConfig));
}
+
+ @Override
+ public boolean isVotingMember() {
+ return votingMember;
+ }
+
+ @Override
+ public RaftActorBehavior getCurrentBehavior() {
+ return currentBehavior;
+ }
+
+ void setCurrentBehavior(final RaftActorBehavior behavior) {
+ this.currentBehavior = Preconditions.checkNotNull(behavior);
+ }
+
+ void close() {
+ if (currentBehavior != null) {
+ try {
+ currentBehavior.close();
+ } catch (Exception e) {
+ LOG.debug("{}: Error closing behavior {}", getId(), currentBehavior.state());
+ }
+ }
+ }
}