Search in sources :

Example 1 with ActorSelection

use of akka.actor.ActorSelection in project flink by apache.

the class FlinkResourceManager method triggerConnectingToJobManager.

/**
	 * Causes the resource manager to announce itself at the new leader JobManager and
	 * obtains its connection information and currently known TaskManagers.
	 *
	 * @param leaderAddress The akka actor URL of the new leader JobManager.
	 */
protected void triggerConnectingToJobManager(String leaderAddress) {
    LOG.info("Trying to associate with JobManager leader " + leaderAddress);
    final Object registerMessage = decorateMessage(new RegisterResourceManager(self()));
    final Object retryMessage = decorateMessage(new TriggerRegistrationAtJobManager(leaderAddress));
    // send the registration message to the JobManager
    ActorSelection jobManagerSel = context().actorSelection(leaderAddress);
    Future<Object> future = Patterns.ask(jobManagerSel, registerMessage, new Timeout(messageTimeout));
    future.onComplete(new OnComplete<Object>() {

        @Override
        public void onComplete(Throwable failure, Object msg) {
            // only process if we haven't been connected in the meantime
            if (jobManager == null) {
                if (msg != null) {
                    if (msg instanceof LeaderSessionMessage && ((LeaderSessionMessage) msg).message() instanceof RegisterResourceManagerSuccessful) {
                        self().tell(msg, ActorRef.noSender());
                    } else {
                        LOG.error("Invalid response type to registration at JobManager: {}", msg);
                        self().tell(retryMessage, ActorRef.noSender());
                    }
                } else {
                    // no success
                    LOG.error("Resource manager could not register at JobManager", failure);
                    self().tell(retryMessage, ActorRef.noSender());
                }
            }
        }
    }, context().dispatcher());
}
Also used : LeaderSessionMessage(org.apache.flink.runtime.messages.JobManagerMessages.LeaderSessionMessage) TriggerRegistrationAtJobManager(org.apache.flink.runtime.clusterframework.messages.TriggerRegistrationAtJobManager) ActorSelection(akka.actor.ActorSelection) Timeout(akka.util.Timeout) RegisterResourceManagerSuccessful(org.apache.flink.runtime.clusterframework.messages.RegisterResourceManagerSuccessful) RegisterResourceManager(org.apache.flink.runtime.clusterframework.messages.RegisterResourceManager)

Example 2 with ActorSelection

use of akka.actor.ActorSelection in project controller by opendaylight.

the class AbstractLeader method handleInstallSnapshotReply.

private void handleInstallSnapshotReply(final InstallSnapshotReply reply) {
    log.debug("{}: handleInstallSnapshotReply: {}", logName(), reply);
    String followerId = reply.getFollowerId();
    FollowerLogInformation followerLogInformation = followerToLog.get(followerId);
    if (followerLogInformation == null) {
        // This can happen during AddServer if it times out.
        log.error("{}: FollowerLogInformation not found for follower {} in InstallSnapshotReply", logName(), followerId);
        return;
    }
    LeaderInstallSnapshotState installSnapshotState = followerLogInformation.getInstallSnapshotState();
    if (installSnapshotState == null) {
        log.error("{}: LeaderInstallSnapshotState not found for follower {} in InstallSnapshotReply", logName(), followerId);
        return;
    }
    followerLogInformation.markFollowerActive();
    if (installSnapshotState.getChunkIndex() == reply.getChunkIndex()) {
        boolean wasLastChunk = false;
        if (reply.isSuccess()) {
            if (installSnapshotState.isLastChunk(reply.getChunkIndex())) {
                // this was the last chunk reply
                long followerMatchIndex = snapshotHolder.get().getLastIncludedIndex();
                followerLogInformation.setMatchIndex(followerMatchIndex);
                followerLogInformation.setNextIndex(followerMatchIndex + 1);
                followerLogInformation.clearLeaderInstallSnapshotState();
                log.info("{}: Snapshot successfully installed on follower {} (last chunk {}) - " + "matchIndex set to {}, nextIndex set to {}", logName(), followerId, reply.getChunkIndex(), followerLogInformation.getMatchIndex(), followerLogInformation.getNextIndex());
                if (!anyFollowersInstallingSnapshot()) {
                    // once there are no pending followers receiving snapshots
                    // we can remove snapshot from the memory
                    setSnapshotHolder(null);
                }
                wasLastChunk = true;
                if (context.getPeerInfo(followerId).getVotingState() == VotingState.VOTING_NOT_INITIALIZED) {
                    UnInitializedFollowerSnapshotReply unInitFollowerSnapshotSuccess = new UnInitializedFollowerSnapshotReply(followerId);
                    context.getActor().tell(unInitFollowerSnapshotSuccess, context.getActor());
                    log.debug("Sent message UnInitializedFollowerSnapshotReply to self");
                }
            } else {
                installSnapshotState.markSendStatus(true);
            }
        } else {
            log.warn("{}: Received failed InstallSnapshotReply - will retry: {}", logName(), reply);
            installSnapshotState.markSendStatus(false);
        }
        if (wasLastChunk) {
            if (!context.getSnapshotManager().isCapturing()) {
                // Since the follower is now caught up try to purge the log.
                purgeInMemoryLog();
            }
        } else {
            ActorSelection followerActor = context.getPeerActorSelection(followerId);
            if (followerActor != null) {
                sendSnapshotChunk(followerActor, followerLogInformation);
            }
        }
    } else {
        log.error("{}: Chunk index {} in InstallSnapshotReply from follower {} does not match expected index {}", logName(), reply.getChunkIndex(), followerId, installSnapshotState.getChunkIndex());
        if (reply.getChunkIndex() == LeaderInstallSnapshotState.INVALID_CHUNK_INDEX) {
            // Since the Follower did not find this index to be valid we should reset the follower snapshot
            // so that Installing the snapshot can resume from the beginning
            installSnapshotState.reset();
        }
    }
}
Also used : FollowerLogInformation(org.opendaylight.controller.cluster.raft.FollowerLogInformation) ActorSelection(akka.actor.ActorSelection) UnInitializedFollowerSnapshotReply(org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply)

Example 3 with ActorSelection

use of akka.actor.ActorSelection in project controller by opendaylight.

the class AbstractLeader method sendUpdatesToFollower.

/**
 * This method checks if any update needs to be sent to the given follower. This includes append log entries,
 * sending next snapshot chunk, and initiating a snapshot.
 */
private void sendUpdatesToFollower(final String followerId, final FollowerLogInformation followerLogInformation, final boolean sendHeartbeat, final boolean isHeartbeat) {
    ActorSelection followerActor = context.getPeerActorSelection(followerId);
    if (followerActor != null) {
        long followerNextIndex = followerLogInformation.getNextIndex();
        boolean isFollowerActive = followerLogInformation.isFollowerActive();
        boolean sendAppendEntries = false;
        List<ReplicatedLogEntry> entries = Collections.emptyList();
        LeaderInstallSnapshotState installSnapshotState = followerLogInformation.getInstallSnapshotState();
        if (installSnapshotState != null) {
            // if install snapshot is in process , then sent next chunk if possible
            if (isFollowerActive && installSnapshotState.canSendNextChunk()) {
                sendSnapshotChunk(followerActor, followerLogInformation);
            } else if (sendHeartbeat) {
                // we send a heartbeat even if we have not received a reply for the last chunk
                sendAppendEntries = true;
            }
        } else if (followerLogInformation.isLogEntrySlicingInProgress()) {
            sendAppendEntries = sendHeartbeat;
        } else {
            long leaderLastIndex = context.getReplicatedLog().lastIndex();
            long leaderSnapShotIndex = context.getReplicatedLog().getSnapshotIndex();
            if (!isHeartbeat && log.isDebugEnabled() || log.isTraceEnabled()) {
                log.debug("{}: Checking sendAppendEntries for follower {}: active: {}, followerNextIndex: {}, " + "leaderLastIndex: {}, leaderSnapShotIndex: {}", logName(), followerId, isFollowerActive, followerNextIndex, leaderLastIndex, leaderSnapShotIndex);
            }
            if (isFollowerActive && context.getReplicatedLog().isPresent(followerNextIndex)) {
                log.debug("{}: sendAppendEntries: {} is present for follower {}", logName(), followerNextIndex, followerId);
                if (followerLogInformation.okToReplicate()) {
                    entries = getEntriesToSend(followerLogInformation, followerActor);
                    sendAppendEntries = true;
                }
            } else if (isFollowerActive && followerNextIndex >= 0 && leaderLastIndex > followerNextIndex && !context.getSnapshotManager().isCapturing()) {
                // if the followers next index is not present in the leaders log, and
                // if the follower is just not starting and if leader's index is more than followers index
                // then snapshot should be sent
                // Send heartbeat to follower whenever install snapshot is initiated.
                sendAppendEntries = true;
                if (canInstallSnapshot(followerNextIndex)) {
                    log.info("{}: Initiating install snapshot to follower {}: follower nextIndex: {}, leader " + "snapshotIndex: {}, leader lastIndex: {}, leader log size: {}", logName(), followerId, followerNextIndex, leaderSnapShotIndex, leaderLastIndex, context.getReplicatedLog().size());
                    initiateCaptureSnapshot(followerId);
                } else {
                    // It doesn't seem like we should ever reach here - most likely indicates sonething is
                    // wrong.
                    log.info("{}: Follower {} is behind but cannot install snapshot: follower nextIndex: {}, " + "leader snapshotIndex: {}, leader lastIndex: {}, leader log size: {}", logName(), followerId, followerNextIndex, leaderSnapShotIndex, leaderLastIndex, context.getReplicatedLog().size());
                }
            } else if (sendHeartbeat) {
                // we send an AppendEntries, even if the follower is inactive
                // in-order to update the followers timestamp, in case it becomes active again
                sendAppendEntries = true;
            }
        }
        if (sendAppendEntries) {
            sendAppendEntriesToFollower(followerActor, entries, followerLogInformation);
        }
    }
}
Also used : ReplicatedLogEntry(org.opendaylight.controller.cluster.raft.ReplicatedLogEntry) ActorSelection(akka.actor.ActorSelection)

Example 4 with ActorSelection

use of akka.actor.ActorSelection in project controller by opendaylight.

the class AbstractLeader method sendInstallSnapshot.

private void sendInstallSnapshot() {
    log.debug("{}: sendInstallSnapshot", logName());
    for (Entry<String, FollowerLogInformation> e : followerToLog.entrySet()) {
        String followerId = e.getKey();
        ActorSelection followerActor = context.getPeerActorSelection(followerId);
        FollowerLogInformation followerLogInfo = e.getValue();
        if (followerActor != null) {
            long nextIndex = followerLogInfo.getNextIndex();
            if (followerLogInfo.getInstallSnapshotState() != null || context.getPeerInfo(followerId).getVotingState() == VotingState.VOTING_NOT_INITIALIZED || canInstallSnapshot(nextIndex)) {
                sendSnapshotChunk(followerActor, followerLogInfo);
            }
        }
    }
}
Also used : FollowerLogInformation(org.opendaylight.controller.cluster.raft.FollowerLogInformation) ActorSelection(akka.actor.ActorSelection)

Example 5 with ActorSelection

use of akka.actor.ActorSelection in project controller by opendaylight.

the class Candidate method startNewTerm.

private void startNewTerm() {
    // set voteCount back to 1 (that is voting for self)
    voteCount = 1;
    // Increment the election term and vote for self
    long currentTerm = context.getTermInformation().getCurrentTerm();
    long newTerm = currentTerm + 1;
    context.getTermInformation().updateAndPersist(newTerm, context.getId());
    log.info("{}: Starting new election term {}", logName(), newTerm);
    // amount of time TBD
    for (String peerId : votingPeers) {
        ActorSelection peerActor = context.getPeerActorSelection(peerId);
        if (peerActor != null) {
            RequestVote requestVote = new RequestVote(context.getTermInformation().getCurrentTerm(), context.getId(), context.getReplicatedLog().lastIndex(), context.getReplicatedLog().lastTerm());
            log.debug("{}: Sending {} to peer {}", logName(), requestVote, peerId);
            peerActor.tell(requestVote, context.getActor());
        }
    }
}
Also used : ActorSelection(akka.actor.ActorSelection) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote)

Aggregations

ActorSelection (akka.actor.ActorSelection)43 ActorRef (akka.actor.ActorRef)9 Test (org.junit.Test)6 PrimaryShardInfo (org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo)5 ActorContext (org.opendaylight.controller.cluster.datastore.utils.ActorContext)4 FollowerLogInformation (org.opendaylight.controller.cluster.raft.FollowerLogInformation)4 InvalidActorNameException (akka.actor.InvalidActorNameException)3 Status (akka.actor.Status)3 TestActorRef (akka.testkit.TestActorRef)3 TestKit (akka.testkit.javadsl.TestKit)3 Timeout (akka.util.Timeout)3 ArrayList (java.util.ArrayList)3 ClientActorContext (org.opendaylight.controller.cluster.access.client.ClientActorContext)3 AkkaException (akka.AkkaException)2 ActorIdentity (akka.actor.ActorIdentity)2 Identify (akka.actor.Identify)2 Failure (akka.actor.Status.Failure)2 Success (akka.actor.Status.Success)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 AbstractActorTest (org.opendaylight.controller.cluster.datastore.AbstractActorTest)2