use of org.neo4j.causalclustering.core.replication.DistributedOperation in project neo4j by neo4j.
the class CommandApplicationProcessTest method outOfOrderDuplicatesShouldBeIgnoredButStillIncreaseCommandIndex.
@Test
public void outOfOrderDuplicatesShouldBeIgnoredButStillIncreaseCommandIndex() throws Exception {
// given
applicationProcess.start();
// when
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 100), globalSession, new LocalOperationId(0, 0))));
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 101), globalSession, new LocalOperationId(0, 1))));
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 102), globalSession, new LocalOperationId(0, 2))));
// duplicate of tx 101
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 101), globalSession, new LocalOperationId(0, 1))));
// duplicate of tx 100
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 100), globalSession, new LocalOperationId(0, 0))));
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 103), globalSession, new LocalOperationId(0, 3))));
raftLog.append(new RaftLogEntry(0, new DistributedOperation(tx((byte) 104), globalSession, new LocalOperationId(0, 4))));
applicationProcess.notifyCommitted(6);
applier.sync(false);
InOrder inOrder = inOrder(coreStateMachines, commandDispatcher);
// then
inOrder.verify(coreStateMachines).commandDispatcher();
inOrder.verify(commandDispatcher).dispatch(eq(tx((byte) 100)), eq(0L), anyCallback());
inOrder.verify(commandDispatcher).dispatch(eq(tx((byte) 101)), eq(1L), anyCallback());
inOrder.verify(commandDispatcher).dispatch(eq(tx((byte) 102)), eq(2L), anyCallback());
// duplicate of tx 101 not dispatched, at index 3
// duplicate of tx 100 not dispatched, at index 4
inOrder.verify(commandDispatcher).dispatch(eq(tx((byte) 103)), eq(5L), anyCallback());
inOrder.verify(commandDispatcher).dispatch(eq(tx((byte) 104)), eq(6L), anyCallback());
inOrder.verify(commandDispatcher).close();
verifyNoMoreInteractions(commandDispatcher);
}
use of org.neo4j.causalclustering.core.replication.DistributedOperation in project neo4j by neo4j.
the class CommandApplicationProcess method handleOperations.
private long handleOperations(long commandIndex, List<DistributedOperation> operations) {
try (CommandDispatcher dispatcher = coreStateMachines.commandDispatcher()) {
for (DistributedOperation operation : operations) {
if (!sessionTracker.validateOperation(operation.globalSession(), operation.operationId())) {
sessionTracker.validateOperation(operation.globalSession(), operation.operationId());
commandIndex++;
continue;
}
CoreReplicatedContent command = (CoreReplicatedContent) operation.content();
command.dispatch(dispatcher, commandIndex, result -> progressTracker.trackResult(operation, result));
sessionTracker.update(operation.globalSession(), operation.operationId(), commandIndex);
commandIndex++;
}
}
return commandIndex - 1;
}
use of org.neo4j.causalclustering.core.replication.DistributedOperation in project neo4j by neo4j.
the class CommandApplicationProcess method submitApplyJob.
private void submitApplyJob(long lastToApply) {
boolean success = applier.submit((status) -> () -> {
final long snapshotLastSeenCommitIndex = this.lastSeenCommitIndex;
try (InFlightLogEntryReader logEntrySupplier = new InFlightLogEntryReader(raftLog, inFlightMap, true)) {
for (long logIndex = lastApplied + 1; !status.isCancelled() && logIndex <= snapshotLastSeenCommitIndex; logIndex++) {
RaftLogEntry entry = logEntrySupplier.get(logIndex);
if (entry == null) {
throw new IllegalStateException(format("Committed log %d entry must exist.", logIndex));
}
if (entry.content() instanceof DistributedOperation) {
DistributedOperation distributedOperation = (DistributedOperation) entry.content();
progressTracker.trackReplication(distributedOperation);
batcher.add(logIndex, distributedOperation);
} else {
batcher.flush();
// since this last entry didn't get in the batcher we need to update the lastApplied:
lastApplied = logIndex;
}
}
batcher.flush();
} catch (Throwable e) {
log.error("Failed to apply up to index " + lastToApply, e);
dbHealth.get().panic(e);
applier.panic();
}
});
if (!success) {
log.error("Applier has entered a state of panic, no more jobs can be submitted.");
try {
// Let's sleep a while so that the log does not get flooded in this state.
// TODO: Consider triggering a shutdown of the database on panic.
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}
use of org.neo4j.causalclustering.core.replication.DistributedOperation in project neo4j by neo4j.
the class CommandApplicationProcessTest method duplicatesShouldBeIgnoredButStillIncreaseCommandIndex.
@Test
public void duplicatesShouldBeIgnoredButStillIncreaseCommandIndex() throws Exception {
// given
applicationProcess.start();
// when
raftLog.append(new RaftLogEntry(0, new NewLeaderBarrier()));
raftLog.append(new RaftLogEntry(0, new DistributedOperation(nullTx, globalSession, new LocalOperationId(0, 0))));
// duplicate
raftLog.append(new RaftLogEntry(0, new DistributedOperation(nullTx, globalSession, new LocalOperationId(0, 0))));
raftLog.append(new RaftLogEntry(0, new DistributedOperation(nullTx, globalSession, new LocalOperationId(0, 1))));
applicationProcess.notifyCommitted(3);
applier.sync(false);
InOrder inOrder = inOrder(coreStateMachines, commandDispatcher);
// then
inOrder.verify(coreStateMachines).commandDispatcher();
inOrder.verify(commandDispatcher).dispatch(eq(nullTx), eq(1L), anyCallback());
// duplicate not dispatched
inOrder.verify(commandDispatcher).dispatch(eq(nullTx), eq(3L), anyCallback());
inOrder.verify(commandDispatcher).close();
verifyNoMoreInteractions(commandDispatcher);
}
Aggregations