X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FShard.java;h=439c2baac83dd42bb426dab7eb8a5dda7a277e54;hb=refs%2Fchanges%2F24%2F32524%2F19;hp=7867c91158b7d939ca9b795c84eb38b383dadb96;hpb=671ee25af46a1f852548de03cd0d3b8f74d7b7ba;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java index 7867c91158..439c2baac8 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java @@ -12,7 +12,6 @@ import akka.actor.ActorRef; import akka.actor.ActorSelection; import akka.actor.Cancellable; import akka.actor.Props; -import akka.persistence.RecoveryFailure; import akka.serialization.Serialization; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; @@ -50,7 +49,6 @@ import org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeCh import org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged; import org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext; import org.opendaylight.controller.cluster.datastore.modification.Modification; -import org.opendaylight.controller.cluster.datastore.modification.ModificationPayload; import org.opendaylight.controller.cluster.datastore.modification.MutableCompositeModification; import org.opendaylight.controller.cluster.datastore.utils.Dispatchers; import org.opendaylight.controller.cluster.datastore.utils.MessageTracker; @@ -189,28 +187,19 @@ public class Shard extends RaftActor { txCommitTimeoutCheckSchedule.cancel(); } + commitCoordinator.abortPendingTransactions("Transaction aborted due to shutdown.", this); + shardMBean.unregisterMBean(); } @Override public void onReceiveRecover(final Object message) throws Exception { - if(LOG.isDebugEnabled()) { - LOG.debug("{}: onReceiveRecover: Received message {} from {}", persistenceId(), - message.getClass().toString(), getSender()); - } + LOG.debug("{}: onReceiveRecover: Received message {} from {}", persistenceId(), message.getClass(), + getSender()); - if (message instanceof RecoveryFailure){ - LOG.error("{}: Recovery failed because of this cause", - persistenceId(), ((RecoveryFailure) message).cause()); - - // Even though recovery failed, we still need to finish our recovery, eg send the - // ActorInitialized message and start the txCommitTimeoutCheckSchedule. - onRecoveryComplete(); - } else { - super.onReceiveRecover(message); - if(LOG.isTraceEnabled()) { - appendEntriesReplyTracker.begin(); - } + super.onReceiveRecover(message); + if (LOG.isTraceEnabled()) { + appendEntriesReplyTracker.begin(); } } @@ -225,7 +214,7 @@ public class Shard extends RaftActor { } try { - if (CreateTransaction.SERIALIZABLE_CLASS.isInstance(message)) { + if (CreateTransaction.isSerializedType(message)) { handleCreateTransaction(message); } else if (BatchedModifications.class.isInstance(message)) { handleBatchedModifications((BatchedModifications)message); @@ -233,13 +222,13 @@ public class Shard extends RaftActor { handleForwardedReadyTransaction((ForwardedReadyTransaction) message); } else if (message instanceof ReadyLocalTransaction) { handleReadyLocalTransaction((ReadyLocalTransaction)message); - } else if (CanCommitTransaction.SERIALIZABLE_CLASS.isInstance(message)) { + } else if (CanCommitTransaction.isSerializedType(message)) { handleCanCommitTransaction(CanCommitTransaction.fromSerializable(message)); - } else if (CommitTransaction.SERIALIZABLE_CLASS.isInstance(message)) { + } else if (CommitTransaction.isSerializedType(message)) { handleCommitTransaction(CommitTransaction.fromSerializable(message)); - } else if (AbortTransaction.SERIALIZABLE_CLASS.isInstance(message)) { + } else if (AbortTransaction.isSerializedType(message)) { handleAbortTransaction(AbortTransaction.fromSerializable(message)); - } else if (CloseTransactionChain.SERIALIZABLE_CLASS.isInstance(message)) { + } else if (CloseTransactionChain.isSerializedType(message)) { closeTransactionChain(CloseTransactionChain.fromSerializable(message)); } else if (message instanceof RegisterChangeListener) { changeSupport.onMessage((RegisterChangeListener) message, isLeader(), hasLeader()); @@ -252,7 +241,7 @@ public class Shard extends RaftActor { setPeerAddress(resolved.getPeerId().toString(), resolved.getPeerAddress()); } else if (message.equals(TX_COMMIT_TIMEOUT_CHECK_MESSAGE)) { - handleTransactionCommitTimeoutCheck(); + commitCoordinator.checkForExpiredTransactions(transactionCommitTimeout, this); } else if(message instanceof DatastoreContext) { onDatastoreContext((DatastoreContext)message); } else if(message instanceof RegisterRoleChangeListener){ @@ -284,6 +273,10 @@ public class Shard extends RaftActor { return commitCoordinator.getQueueSize(); } + public int getCohortCacheSize() { + return commitCoordinator.getCohortCacheSize(); + } + @Override protected Optional getRoleChangeNotifier() { return roleChangeNotifier; @@ -312,20 +305,6 @@ public class Shard extends RaftActor { updateConfigParams(datastoreContext.getShardRaftConfig()); } - private void handleTransactionCommitTimeoutCheck() { - CohortEntry cohortEntry = commitCoordinator.getCurrentCohortEntry(); - if(cohortEntry != null) { - if(cohortEntry.isExpired(transactionCommitTimeout)) { - LOG.warn("{}: Current transaction {} has timed out after {} ms - aborting", - persistenceId(), cohortEntry.getTransactionID(), transactionCommitTimeout); - - doAbortTransaction(cohortEntry.getTransactionID(), null); - } - } - - commitCoordinator.cleanupExpiredCohortEntries(); - } - private static boolean isEmptyCommit(final DataTreeCandidate candidate) { return ModificationType.UNMODIFIED.equals(candidate.getRootNode().getModificationType()); } @@ -356,7 +335,7 @@ public class Shard extends RaftActor { try { cohortEntry.commit(); - sender.tell(CommitTransactionReply.INSTANCE.toSerializable(), getSelf()); + sender.tell(CommitTransactionReply.instance(cohortEntry.getClientVersion()).toSerializable(), getSelf()); shardMBean.incrementCommittedTransactionCount(); shardMBean.setLastCommittedTransactionTime(System.currentTimeMillis()); @@ -393,7 +372,8 @@ public class Shard extends RaftActor { LOG.error("{}: Failed to re-apply transaction {}", persistenceId(), transactionID, e); } - sender.tell(CommitTransactionReply.INSTANCE.toSerializable(), getSelf()); + sender.tell(CommitTransactionReply.instance(cohortEntry.getClientVersion()).toSerializable(), + getSelf()); } else { // This really shouldn't happen - it likely means that persistence or replication // took so long to complete such that the cohort entry was expired from the cache. @@ -436,12 +416,12 @@ public class Shard extends RaftActor { // 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 isIsolatedLeader = isIsolatedLeader(); - if (isLeader() && !isIsolatedLeader) { + boolean isLeaderActive = isLeaderActive(); + if (isLeader() && isLeaderActive) { handleBatchedModificationsLocal(batched, getSender()); } else { ActorSelection leader = getLeader(); - if (isIsolatedLeader || leader == null) { + if (!isLeaderActive || leader == null) { messageRetrySupport.addMessageToRetry(batched, getSender(), "Could not commit transaction " + batched.getTransactionID()); } else { @@ -473,8 +453,8 @@ public class Shard extends RaftActor { private void handleReadyLocalTransaction(final ReadyLocalTransaction message) { LOG.debug("{}: handleReadyLocalTransaction for {}", persistenceId(), message.getTransactionID()); - boolean isIsolatedLeader = isIsolatedLeader(); - if (isLeader() && !isIsolatedLeader) { + boolean isLeaderActive = isLeaderActive(); + if (isLeader() && isLeaderActive) { try { commitCoordinator.handleReadyLocalTransaction(message, getSender(), this); } catch (Exception e) { @@ -484,7 +464,7 @@ public class Shard extends RaftActor { } } else { ActorSelection leader = getLeader(); - if (isIsolatedLeader || leader == null) { + if (!isLeaderActive || leader == null) { messageRetrySupport.addMessageToRetry(message, getSender(), "Could not commit transaction " + message.getTransactionID()); } else { @@ -498,12 +478,12 @@ public class Shard extends RaftActor { private void handleForwardedReadyTransaction(ForwardedReadyTransaction forwardedReady) { LOG.debug("{}: handleForwardedReadyTransaction for {}", persistenceId(), forwardedReady.getTransactionID()); - boolean isIsolatedLeader = isIsolatedLeader(); - if (isLeader() && !isIsolatedLeader) { + boolean isLeaderActive = isLeaderActive(); + if (isLeader() && isLeaderActive) { commitCoordinator.handleForwardedReadyTransaction(forwardedReady, getSender(), this); } else { ActorSelection leader = getLeader(); - if (isIsolatedLeader || leader == null) { + if (!isLeaderActive || leader == null) { messageRetrySupport.addMessageToRetry(forwardedReady, getSender(), "Could not commit transaction " + forwardedReady.getTransactionID()); } else { @@ -541,11 +521,10 @@ public class Shard extends RaftActor { } private ActorRef createTypedTransactionActor(int transactionType, - ShardTransactionIdentifier transactionId, String transactionChainId, - short clientVersion ) { + ShardTransactionIdentifier transactionId, String transactionChainId) { return transactionActorFactory.newShardTransaction(TransactionType.fromInt(transactionType), - transactionId, transactionChainId, clientVersion); + transactionId, transactionChainId); } private void createTransaction(CreateTransaction createTransaction) { @@ -556,18 +535,17 @@ public class Shard extends RaftActor { } ActorRef transactionActor = createTransaction(createTransaction.getTransactionType(), - createTransaction.getTransactionId(), createTransaction.getTransactionChainId(), - createTransaction.getVersion()); + createTransaction.getTransactionId(), createTransaction.getTransactionChainId()); getSender().tell(new CreateTransactionReply(Serialization.serializedActorPath(transactionActor), - createTransaction.getTransactionId()).toSerializable(), getSelf()); + createTransaction.getTransactionId(), createTransaction.getVersion()).toSerializable(), getSelf()); } catch (Exception e) { getSender().tell(new akka.actor.Status.Failure(e), getSelf()); } } private ActorRef createTransaction(int transactionType, String remoteTransactionId, - String transactionChainId, short clientVersion) { + String transactionChainId) { ShardTransactionIdentifier transactionId = new ShardTransactionIdentifier(remoteTransactionId); @@ -577,7 +555,7 @@ public class Shard extends RaftActor { } ActorRef transactionActor = createTypedTransactionActor(transactionType, transactionId, - transactionChainId, clientVersion); + transactionChainId); return transactionActor; } @@ -654,12 +632,6 @@ public class Shard extends RaftActor { // Replication consensus reached, proceed to commit finishCommit(clientActor, identifier); } - } else if (data instanceof ModificationPayload) { - try { - applyModificationToState(clientActor, identifier, ((ModificationPayload) data).getModification()); - } catch (ClassNotFoundException | IOException e) { - LOG.error("{}: Error extracting ModificationPayload", persistenceId(), e); - } } else if (data instanceof CompositeModificationPayload) { Object modification = ((CompositeModificationPayload) data).getModification(); @@ -706,6 +678,9 @@ public class Shard extends RaftActor { } store.closeAllTransactionChains(); + + commitCoordinator.abortPendingTransactions( + "The transacton was aborted due to inflight leadership change.", this); } if(hasLeader && !isIsolatedLeader()) { @@ -722,6 +697,12 @@ public class Shard extends RaftActor { } } + @Override + protected void pauseLeader(Runnable operation) { + LOG.debug("{}: In pauseLeader, operation: {}", persistenceId(), operation); + commitCoordinator.setRunOnPendingTransactionsComplete(operation); + } + @Override public String persistenceId() { return this.name;