use of akka.actor.ActorSelection in project controller by opendaylight.
the class Shard method handleBatchedModifications.
private void handleBatchedModifications(final BatchedModifications batched) {
// This message is sent to prepare the modifications transaction directly on the Shard as an
// optimization to avoid the extra overhead of a separate ShardTransaction actor. On the last
// BatchedModifications message, the caller sets the ready flag in the message indicating
// modifications are complete. The reply contains the cohort actor path (this actor) for the caller
// to initiate the 3-phase commit. This also avoids the overhead of sending an additional
// ReadyTransaction message.
// If we're not the leader then forward to the leader. This is a safety measure - we shouldn't
// normally get here if we're not the leader as the front-end (TransactionProxy) should determine
// the primary/leader shard. However with timing and caching on the front-end, there's a small
// window where it could have a stale leader during leadership transitions.
//
boolean isLeaderActive = isLeaderActive();
if (isLeader() && isLeaderActive) {
handleBatchedModificationsLocal(batched, getSender());
} else {
ActorSelection leader = getLeader();
if (!isLeaderActive || leader == null) {
messageRetrySupport.addMessageToRetry(batched, getSender(), "Could not process BatchedModifications " + batched.getTransactionId());
} else {
// If this is not the first batch and leadership changed in between batched messages,
// we need to reconstruct previous BatchedModifications from the transaction
// DataTreeModification, honoring the max batched modification count, and forward all the
// previous BatchedModifications to the new leader.
Collection<BatchedModifications> newModifications = commitCoordinator.createForwardedBatchedModifications(batched, datastoreContext.getShardBatchedModificationCount());
LOG.debug("{}: Forwarding {} BatchedModifications to leader {}", persistenceId(), newModifications.size(), leader);
for (BatchedModifications bm : newModifications) {
leader.forward(bm, getContext());
}
}
}
}
use of akka.actor.ActorSelection in project controller by opendaylight.
the class Shard method handleCommitTransaction.
private void handleCommitTransaction(final CommitTransaction commit) {
if (isLeader()) {
commitCoordinator.handleCommit(commit.getTransactionId(), getSender(), this);
} else {
ActorSelection leader = getLeader();
if (leader == null) {
messageRetrySupport.addMessageToRetry(commit, getSender(), "Could not commit transaction " + commit.getTransactionId());
} else {
LOG.debug("{}: Forwarding CommitTransaction to leader {}", persistenceId(), leader);
leader.forward(commit, getContext());
}
}
}
use of akka.actor.ActorSelection in project controller by opendaylight.
the class Shard method handleForwardedReadyTransaction.
private void handleForwardedReadyTransaction(final ForwardedReadyTransaction forwardedReady) {
LOG.debug("{}: handleForwardedReadyTransaction for {}", persistenceId(), forwardedReady.getTransactionId());
boolean isLeaderActive = isLeaderActive();
if (isLeader() && isLeaderActive) {
commitCoordinator.handleForwardedReadyTransaction(forwardedReady, getSender(), this);
} else {
ActorSelection leader = getLeader();
if (!isLeaderActive || leader == null) {
messageRetrySupport.addMessageToRetry(forwardedReady, getSender(), "Could not process forwarded ready transaction " + forwardedReady.getTransactionId());
} else {
LOG.debug("{}: Forwarding ForwardedReadyTransaction to leader {}", persistenceId(), leader);
ReadyLocalTransaction readyLocal = new ReadyLocalTransaction(forwardedReady.getTransactionId(), forwardedReady.getTransaction().getSnapshot(), forwardedReady.isDoImmediateCommit());
readyLocal.setRemoteVersion(getCurrentBehavior().getLeaderPayloadVersion());
leader.forward(readyLocal, getContext());
}
}
}
use of akka.actor.ActorSelection in project controller by opendaylight.
the class Shard method onLeaderChanged.
@Override
protected void onLeaderChanged(final String oldLeader, final String newLeader) {
shardMBean.incrementLeadershipChangeCount();
paused = false;
if (!isLeader()) {
if (!knownFrontends.isEmpty()) {
LOG.debug("{}: removing frontend state for {}", persistenceId(), knownFrontends.keySet());
knownFrontends = ImmutableMap.of();
}
requestMessageAssembler.close();
if (!hasLeader()) {
// No leader anywhere, nothing else to do
return;
}
// Another leader was elected. If we were the previous leader and had pending transactions, convert
// them to transaction messages and send to the new leader.
ActorSelection leader = getLeader();
if (leader != null) {
Collection<?> messagesToForward = convertPendingTransactionsToMessages();
if (!messagesToForward.isEmpty()) {
LOG.debug("{}: Forwarding {} pending transaction messages to leader {}", persistenceId(), messagesToForward.size(), leader);
for (Object message : messagesToForward) {
leader.tell(message, self());
}
}
} else {
commitCoordinator.abortPendingTransactions("The transacton was aborted due to inflight leadership " + "change and the leader address isn't available.", this);
}
} else {
// We have become the leader, we need to reconstruct frontend state
knownFrontends = Verify.verifyNotNull(frontendMetadata.toLeaderState(this));
LOG.debug("{}: became leader with frontend state for {}", persistenceId(), knownFrontends.keySet());
}
if (!isIsolatedLeader()) {
messageRetrySupport.retryMessages();
}
}
use of akka.actor.ActorSelection in project controller by opendaylight.
the class AbstractDataListenerSupport method processListenerRegistrationMessage.
protected ActorSelection processListenerRegistrationMessage(M message) {
final ActorSelection listenerActor = selectActor(message.getListenerActorPath());
// We have a leader so enable the listener.
listenerActor.tell(new EnableNotification(true, persistenceId()), getSelf());
if (!message.isRegisterOnAllInstances()) {
// This is a leader-only registration so store a reference to the listener actor so it can be notified
// at a later point if notifications should be enabled or disabled.
leaderOnlyListenerActors.add(listenerActor);
}
allListenerActors.add(listenerActor);
return listenerActor;
}
Aggregations