use of org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload in project controller by opendaylight.
the class ShardTest method testAbortWithCommitPending.
@Test
public void testAbortWithCommitPending() throws Exception {
new ShardTestKit(getSystem()) {
{
final Creator<Shard> creator = () -> new Shard(newShardBuilder()) {
@Override
void persistPayload(final Identifier id, final Payload payload, final boolean batchHint) {
// Simulate an AbortTransaction message occurring during
// replication, after
// persisting and before finishing the commit to the
// in-memory store.
doAbortTransaction(id, null);
super.persistPayload(id, payload, batchHint);
}
};
final TestActorRef<Shard> shard = actorFactory.createTestActor(Props.create(new DelegatingShardCreator(creator)).withDispatcher(Dispatchers.DefaultDispatcherId()), "testAbortWithCommitPending");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
final TransactionIdentifier transactionID = nextTransactionId();
shard.tell(prepareBatchedModifications(transactionID, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), false), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
shard.tell(new CanCommitTransaction(transactionID, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CanCommitTransactionReply.class);
shard.tell(new CommitTransaction(transactionID, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CommitTransactionReply.class);
final NormalizedNode<?, ?> node = readStore(shard, TestModel.TEST_PATH);
// Since we're simulating an abort occurring during replication
// and before finish commit,
// the data should still get written to the in-memory store
// since we've gotten past
// canCommit and preCommit and persisted the data.
assertNotNull(TestModel.TEST_QNAME.getLocalName() + " not found", node);
}
};
}
use of org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload in project controller by opendaylight.
the class AbstractRaftActorBehaviorTest method assertStateChangesToFollowerWhenRaftRPCHasNewerTerm.
protected void assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(final MockRaftActorContext actorContext, final ActorRef actorRef, final RaftRPC rpc) {
Payload payload = new MockRaftActorContext.MockPayload("");
setLastLogEntry(actorContext, 1, 0, payload);
actorContext.getTermInformation().update(1, "test");
RaftActorBehavior origBehavior = createBehavior(actorContext);
RaftActorBehavior raftBehavior = origBehavior.handleMessage(actorRef, rpc);
assertEquals("New raft state", RaftState.Follower, raftBehavior.state());
assertEquals("New election term", rpc.getTerm(), actorContext.getTermInformation().getCurrentTerm());
origBehavior.close();
raftBehavior.close();
}
use of org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload in project controller by opendaylight.
the class ShardDataTree method startCommit.
void startCommit(final SimpleShardDataTreeCohort cohort, final DataTreeCandidate candidate) {
final CommitEntry entry = pendingCommits.peek();
Preconditions.checkState(entry != null, "Attempted to start commit of %s when no transactions pending", cohort);
final SimpleShardDataTreeCohort current = entry.cohort;
if (!cohort.equals(current)) {
LOG.debug("{}: Transaction {} scheduled for commit step", logContext, cohort.getIdentifier());
return;
}
LOG.debug("{}: Starting commit for transaction {}", logContext, current.getIdentifier());
final TransactionIdentifier txId = cohort.getIdentifier();
final Payload payload;
try {
payload = CommitTransactionPayload.create(txId, candidate);
} catch (IOException e) {
LOG.error("{}: Failed to encode transaction {} candidate {}", logContext, txId, candidate, e);
pendingCommits.poll().cohort.failedCommit(e);
processNextPending();
return;
}
// We process next transactions pending canCommit before we call persistPayload to possibly progress subsequent
// transactions to the COMMIT_PENDING state so the payloads can be batched for replication. This is done for
// single-shard transactions that immediately transition from canCommit to preCommit to commit. Note that
// if the next pending transaction is progressed to COMMIT_PENDING and this method (startCommit) is called,
// the next transaction will not attempt to replicate b/c the current transaction is still at the head of the
// pendingCommits queue.
processNextPendingTransaction();
// After processing next pending transactions, we can now remove the current transaction from pendingCommits.
// Note this must be done before the call to peekNextPendingCommit below so we check the next transaction
// in order to properly determine the batchHint flag for the call to persistPayload.
pendingCommits.remove();
pendingFinishCommits.add(entry);
// See if the next transaction is pending commit (ie in the COMMIT_PENDING state) so it can be batched with
// this transaction for replication.
boolean replicationBatchHint = peekNextPendingCommit();
// Once completed, we will continue via payloadReplicationComplete
shard.persistPayload(txId, payload, replicationBatchHint);
entry.lastAccess = shard.ticker().read();
LOG.debug("{}: Transaction {} submitted to persistence", logContext, txId);
// Process the next transaction pending commit, if any. If there is one it will be batched with this
// transaction for replication.
processNextPendingCommit();
}
use of org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload in project controller by opendaylight.
the class RaftActor method handleApplyState.
private void handleApplyState(final ApplyState applyState) {
long startTime = System.nanoTime();
Payload payload = applyState.getReplicatedLogEntry().getData();
if (LOG.isDebugEnabled()) {
LOG.debug("{}: Applying state for log index {} data {}", persistenceId(), applyState.getReplicatedLogEntry().getIndex(), payload);
}
if (!(payload instanceof NoopPayload) && !(payload instanceof ServerConfigurationPayload)) {
applyState(applyState.getClientActor(), applyState.getIdentifier(), payload);
}
long elapsedTime = System.nanoTime() - startTime;
if (elapsedTime >= APPLY_STATE_DELAY_THRESHOLD_IN_NANOS) {
LOG.debug("ApplyState took more time than expected. Elapsed Time = {} ms ApplyState = {}", TimeUnit.NANOSECONDS.toMillis(elapsedTime), applyState);
}
// Send the ApplyState message back to self to handle further processing asynchronously.
self().tell(applyState, self());
}
Aggregations