X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2FRaftActor.java;h=dc97336a49d1e1dfdb7067a9aeaed37d2ebc6f67;hp=7ec9f2743c7b6472af4e6ccf521e7c5b4f030e02;hb=refs%2Fchanges%2F09%2F83009%2F6;hpb=c50fd31278f5f24ed487a6f6021f6065bc2fe93f diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java old mode 100644 new mode 100755 index 7ec9f2743c..dc97336a49 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java @@ -6,27 +6,27 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.controller.cluster.raft; +import static com.google.common.base.Verify.verify; +import static java.util.Objects.requireNonNull; + import akka.actor.ActorRef; import akka.actor.ActorSelection; import akka.actor.PoisonPill; import akka.actor.Status; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Verify; import com.google.common.collect.Lists; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.apache.commons.lang3.time.DurationFormatUtils; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.controller.cluster.DataPersistenceProvider; import org.opendaylight.controller.cluster.DelegatingPersistentDataProvider; import org.opendaylight.controller.cluster.NonPersistentDataProvider; @@ -123,8 +123,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { private boolean shuttingDown; - protected RaftActor(String id, Map peerAddresses, - Optional configParams, short payloadVersion) { + protected RaftActor(final String id, final Map peerAddresses, + final Optional configParams, final short payloadVersion) { persistentProvider = new PersistentDataProvider(this); delegatingPersistenceProvider = new RaftActorDelegatingPersistentDataProvider(null, persistentProvider); @@ -133,7 +133,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { this.getContext(), id, new ElectionTermImpl(persistentProvider, id, LOG), -1, -1, peerAddresses, configParams.isPresent() ? configParams.get() : new DefaultConfigParamsImpl(), - delegatingPersistenceProvider, this::handleApplyState, LOG); + delegatingPersistenceProvider, this::handleApplyState, LOG, this::executeInSelf); context.setPayloadVersion(payloadVersion); context.setReplicatedLog(ReplicatedLogImpl.newInstance(context)); @@ -157,7 +157,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } @Override - protected void handleRecover(Object message) { + protected void handleRecover(final Object message) { if (raftRecovery == null) { raftRecovery = newRaftActorRecoverySupport(); } @@ -183,7 +183,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { @VisibleForTesting @SuppressWarnings("checkstyle:IllegalCatch") - protected void changeCurrentBehavior(RaftActorBehavior newBehavior) { + protected void changeCurrentBehavior(final RaftActorBehavior newBehavior) { final RaftActorBehavior currentBehavior = getCurrentBehavior(); if (currentBehavior != null) { try { @@ -277,7 +277,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { // non-leader cannot satisfy leadership request LOG.warn("{}: onRequestLeadership {} was sent to non-leader." + " Current behavior: {}. Sending failure response", - persistenceId(), getCurrentBehavior().state()); + persistenceId(), message, getCurrentBehavior().state()); message.getReplyTo().tell(new LeadershipTransferFailedException("Cannot transfer leader to " + message.getRequestedFollowerId() + ". RequestLeadership message was sent to non-leader " + persistenceId()), getSelf()); @@ -327,7 +327,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } private void initiateLeadershipTransfer(final RaftActorLeadershipTransferCohort.OnComplete onComplete, - @Nullable final String followerId, long newLeaderTimeoutInMillis) { + final @Nullable String followerId, final long newLeaderTimeoutInMillis) { LOG.debug("{}: Initiating leader transfer", persistenceId()); RaftActorLeadershipTransferCohort leadershipTransferInProgress = context.getRaftActorLeadershipTransferCohort(); @@ -336,12 +336,12 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { leadershipTransferInProgress.setNewLeaderTimeoutInMillis(newLeaderTimeoutInMillis); leadershipTransferInProgress.addOnComplete(new RaftActorLeadershipTransferCohort.OnComplete() { @Override - public void onSuccess(ActorRef raftActorRef) { + public void onSuccess(final ActorRef raftActorRef) { context.setRaftActorLeadershipTransferCohort(null); } @Override - public void onFailure(ActorRef raftActorRef) { + public void onFailure(final ActorRef raftActorRef) { context.setRaftActorLeadershipTransferCohort(null); } }); @@ -381,13 +381,13 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { if (context.hasFollowers()) { initiateLeadershipTransfer(new RaftActorLeadershipTransferCohort.OnComplete() { @Override - public void onSuccess(ActorRef raftActorRef) { + public void onSuccess(final ActorRef raftActorRef) { LOG.debug("{}: leader transfer succeeded - sending PoisonPill", persistenceId()); raftActorRef.tell(PoisonPill.getInstance(), raftActorRef); } @Override - public void onFailure(ActorRef raftActorRef) { + public void onFailure(final ActorRef raftActorRef) { LOG.debug("{}: leader transfer failed - sending PoisonPill", persistenceId()); raftActorRef.tell(PoisonPill.getInstance(), raftActorRef); } @@ -417,13 +417,13 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } } - private void switchBehavior(SwitchBehavior message) { + private void switchBehavior(final SwitchBehavior message) { if (!getRaftActorContext().getRaftPolicy().automaticElectionsEnabled()) { RaftState newState = message.getNewState(); if (newState == RaftState.Leader || newState == RaftState.Follower) { + getRaftActorContext().getTermInformation().updateAndPersist(message.getNewTerm(), ""); switchBehavior(behaviorStateTracker.capture(getCurrentBehavior()), AbstractRaftActorBehavior.createBehavior(context, message.getNewState())); - getRaftActorContext().getTermInformation().updateAndPersist(message.getNewTerm(), ""); } else { LOG.warn("Switching to behavior : {} - not supported", newState); } @@ -451,7 +451,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } final RaftActorBehavior currentBehavior = context.getCurrentBehavior(); - OnDemandRaftState.AbstractBuilder builder = newOnDemandRaftStateBuilder() + OnDemandRaftState.AbstractBuilder builder = newOnDemandRaftStateBuilder() .commitIndex(context.getCommitIndex()) .currentTerm(context.getTermInformation().getCurrentTerm()) .inMemoryJournalDataSize(replicatedLog().dataSize()) @@ -484,7 +484,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { for (String id: followerIds) { final FollowerLogInformation info = leader.getFollower(id); followerInfoList.add(new FollowerInfo(id, info.getNextIndex(), info.getMatchIndex(), - info.isFollowerActive(), DurationFormatUtils.formatDurationHMS(info.timeSinceLastActivity()), + info.isFollowerActive(), DurationFormatUtils.formatDurationHMS( + TimeUnit.NANOSECONDS.toMillis(info.nanosSinceLastActivity())), context.getPeerInfo(info.getId()).isVoting())); } @@ -495,11 +496,11 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } - protected OnDemandRaftState.AbstractBuilder newOnDemandRaftStateBuilder() { + protected OnDemandRaftState.AbstractBuilder newOnDemandRaftStateBuilder() { return OnDemandRaftState.builder(); } - private void handleBehaviorChange(BehaviorState oldBehaviorState, RaftActorBehavior currentBehavior) { + private void handleBehaviorChange(final BehaviorState oldBehaviorState, final RaftActorBehavior currentBehavior) { RaftActorBehavior oldBehavior = oldBehaviorState.getBehavior(); if (oldBehavior != currentBehavior) { @@ -537,7 +538,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } } - private void handleApplyState(ApplyState applyState) { + private void handleApplyState(final ApplyState applyState) { long startTime = System.nanoTime(); Payload payload = applyState.getReplicatedLogEntry().getData(); @@ -560,7 +561,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { self().tell(applyState, self()); } - protected LeaderStateChanged newLeaderStateChanged(String memberId, String leaderId, short leaderPayloadVersion) { + protected LeaderStateChanged newLeaderStateChanged(final String memberId, final String leaderId, + final short leaderPayloadVersion) { return new LeaderStateChanged(memberId, leaderId, leaderPayloadVersion); } @@ -637,7 +639,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } @VisibleForTesting - void setCurrentBehavior(RaftActorBehavior behavior) { + void setCurrentBehavior(final RaftActorBehavior behavior) { context.setCurrentBehavior(behavior); } @@ -704,7 +706,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { return context; } - protected void updateConfigParams(ConfigParams configParams) { + protected void updateConfigParams(final ConfigParams configParams) { // obtain the RaftPolicy for oldConfigParams and the updated one. String oldRaftPolicy = context.getConfigParams().getCustomRaftPolicyImplementationClass(); @@ -736,11 +738,11 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { return delegatingPersistenceProvider.getDelegate(); } - public void setPersistence(DataPersistenceProvider provider) { + public void setPersistence(final DataPersistenceProvider provider) { delegatingPersistenceProvider.setDelegate(provider); } - protected void setPersistence(boolean persistent) { + protected void setPersistence(final boolean persistent) { DataPersistenceProvider currentPersistence = persistence(); if (persistent && (currentPersistence == null || !currentPersistence.isRecoveryApplicable())) { setPersistence(new PersistentDataProvider(this)); @@ -750,8 +752,8 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { captureSnapshot(); } } else if (!persistent && (currentPersistence == null || currentPersistence.isRecoveryApplicable())) { - setPersistence(new NonPersistentDataProvider() { - /** + setPersistence(new NonPersistentDataProvider(this) { + /* * The way snapshotting works is, *
    *
  1. RaftActor calls createSnapshot on the Shard @@ -763,7 +765,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { *
*/ @Override - public void saveSnapshot(Object object) { + public void saveSnapshot(final Object object) { // Make saving Snapshot successful // Committing the snapshot here would end up calling commit in the creating state which would // be a state violation. That's why now we send a message to commit the snapshot. @@ -786,7 +788,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { * Note that if the peerId does not match the list of peers passed to * this actor during construction an IllegalStateException will be thrown. */ - protected void setPeerAddress(String peerId, String peerAddress) { + protected void setPeerAddress(final String peerId, final String peerAddress) { context.setPeerAddress(peerId, peerAddress); } @@ -812,8 +814,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { /** * Returns the RaftActorRecoveryCohort to participate in persistence recovery. */ - @Nonnull - protected abstract RaftActorRecoveryCohort getRaftActorRecoveryCohort(); + protected abstract @NonNull RaftActorRecoveryCohort getRaftActorRecoveryCohort(); /** * This method is called when recovery is complete. @@ -823,8 +824,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { /** * Returns the RaftActorSnapshotCohort to participate in snapshot captures. */ - @Nonnull - protected abstract RaftActorSnapshotCohort getRaftActorSnapshotCohort(); + protected abstract @NonNull RaftActorSnapshotCohort getRaftActorSnapshotCohort(); /** * This method will be called by the RaftActor when the state of the @@ -840,6 +840,12 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { */ protected abstract Optional getRoleChangeNotifier(); + /** + * This method is called on the leader when a voting change operation completes. + */ + protected void onVotingStateChangeComplete() { + } + /** * This method is called prior to operations such as leadership transfer and actor shutdown when the leader * must pause or stop its duties. This method allows derived classes to gracefully pause or finish current @@ -852,11 +858,22 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { * * @param operation the operation to run */ - protected void pauseLeader(Runnable operation) { + protected void pauseLeader(final Runnable operation) { operation.run(); } - protected void onLeaderChanged(String oldLeader, String newLeader) { + /** + * This method is invoked when the actions hooked to the leader becoming paused failed to execute and the leader + * should resume normal operations. + * + *

+ * Note this method can be invoked even before the operation supplied to {@link #pauseLeader(Runnable)} is invoked. + */ + protected void unpauseLeader() { + + } + + protected void onLeaderChanged(final String oldLeader, final String newLeader) { } private String getLeaderAddress() { @@ -897,13 +914,13 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { if (isLeader()) { initiateLeadershipTransfer(new RaftActorLeadershipTransferCohort.OnComplete() { @Override - public void onSuccess(ActorRef raftActorRef) { + public void onSuccess(final ActorRef raftActorRef) { LOG.debug("{}: leader transfer succeeded after change to non-voting", persistenceId()); ensureFollowerState(); } @Override - public void onFailure(ActorRef raftActorRef) { + public void onFailure(final ActorRef raftActorRef) { LOG.debug("{}: leader transfer failed after change to non-voting", persistenceId()); ensureFollowerState(); } @@ -929,7 +946,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { @Nullable abstract String getLastLeaderId(); - @Nullable abstract short getLeaderPayloadVersion(); + abstract short getLeaderPayloadVersion(); } /** @@ -945,7 +962,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { final RaftActorBehavior behavior) { this.lastValidLeaderId = lastValidLeaderId; this.lastLeaderId = lastLeaderId; - this.behavior = Preconditions.checkNotNull(behavior); + this.behavior = requireNonNull(behavior); this.leaderPayloadVersion = behavior.getLeaderPayloadVersion(); } @@ -1008,7 +1025,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { BehaviorState capture(final RaftActorBehavior behavior) { if (behavior == null) { - Verify.verify(lastValidLeaderId == null, "Null behavior with non-null last leader"); + verify(lastValidLeaderId == null, "Null behavior with non-null last leader"); return NULL_BEHAVIOR_STATE; } @@ -1020,5 +1037,4 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { return new SimpleBehaviorState(lastValidLeaderId, lastLeaderId, behavior); } } - }