use of org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation in project neo4j by neo4j.
the class TxPullRequestHandler method channelRead0.
@Override
protected void channelRead0(ChannelHandlerContext ctx, final TxPullRequest msg) throws Exception {
long firstTxId = Math.max(msg.previousTxId(), BASE_TX_ID) + 1;
long lastTxId = firstTxId;
CatchupResult status = SUCCESS_END_OF_STREAM;
StoreId localStoreId = storeIdSupplier.get();
long lastCommittedTransactionId = transactionIdStore.getLastCommittedTransactionId();
if (localStoreId == null || !localStoreId.equals(msg.expectedStoreId())) {
status = E_STORE_ID_MISMATCH;
log.info("Failed to serve TxPullRequest for tx %d and storeId %s because that storeId is different " + "from this machine with %s", lastTxId, msg.expectedStoreId(), localStoreId);
} else if (!databaseAvailable.getAsBoolean()) {
// database is not available for pulling transactions...
status = E_STORE_UNAVAILABLE;
log.info("Failed to serve TxPullRequest for tx %d because the local database is unavailable.", lastTxId);
} else if (lastCommittedTransactionId >= firstTxId) {
try (IOCursor<CommittedTransactionRepresentation> cursor = logicalTransactionStore.getTransactions(firstTxId)) {
status = SUCCESS_END_OF_BATCH;
for (int i = 0; i < batchSize; i++) {
if (cursor.next()) {
ctx.write(ResponseMessageType.TX);
CommittedTransactionRepresentation tx = cursor.get();
lastTxId = tx.getCommitEntry().getTxId();
ctx.write(new TxPullResponse(localStoreId, tx));
} else {
status = SUCCESS_END_OF_STREAM;
break;
}
}
ctx.flush();
} catch (NoSuchTransactionException e) {
status = E_TRANSACTION_PRUNED;
log.info("Failed to serve TxPullRequest for tx %d because the transaction does not exist.", lastTxId);
}
}
ctx.write(ResponseMessageType.TX_STREAM_FINISHED);
TxStreamFinishedResponse response = new TxStreamFinishedResponse(status, lastCommittedTransactionId);
ctx.write(response);
ctx.flush();
monitor.increment();
protocol.expect(State.MESSAGE_TYPE);
}
use of org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation in project neo4j by neo4j.
the class ResponsePackerTest method shouldHaveFixedTargetTransactionIdEvenIfLastTransactionIdIsMoving.
@Test
public void shouldHaveFixedTargetTransactionIdEvenIfLastTransactionIdIsMoving() throws Exception {
// GIVEN
LogicalTransactionStore transactionStore = mock(LogicalTransactionStore.class);
long lastAppliedTransactionId = 5L;
TransactionCursor endlessCursor = new EndlessCursor(lastAppliedTransactionId + 1);
when(transactionStore.getTransactions(anyLong())).thenReturn(endlessCursor);
final long targetTransactionId = 8L;
final TransactionIdStore transactionIdStore = new DeadSimpleTransactionIdStore(targetTransactionId, 0, BASE_TX_COMMIT_TIMESTAMP, 0, 0);
ResponsePacker packer = new ResponsePacker(transactionStore, transactionIdStore, Suppliers.singleton(StoreIdTestFactory.newStoreIdForCurrentVersion()));
// WHEN
Response<Object> response = packer.packTransactionStreamResponse(requestContextStartingAt(5L), null);
final AtomicLong nextExpectedVisit = new AtomicLong(lastAppliedTransactionId);
response.accept(new Response.Handler() {
@Override
public void obligation(long txId) throws IOException {
fail("Should not be called");
}
@Override
public Visitor<CommittedTransactionRepresentation, Exception> transactions() {
return new Visitor<CommittedTransactionRepresentation, Exception>() {
@Override
public boolean visit(CommittedTransactionRepresentation element) {
// THEN
long txId = element.getCommitEntry().getTxId();
assertThat(txId, lessThanOrEqualTo(targetTransactionId));
assertEquals(nextExpectedVisit.incrementAndGet(), txId);
// Move the target transaction id forward one step, effectively always keeping it out of reach
transactionIdStore.setLastCommittedAndClosedTransactionId(transactionIdStore.getLastCommittedTransactionId() + 1, 0, BASE_TX_COMMIT_TIMESTAMP, 3, 4);
return true;
}
};
}
});
}
use of org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation in project neo4j by neo4j.
the class MadeUpServerImplementation method streamBackTransactions.
@Override
public Response<Integer> streamBackTransactions(int responseToSendBack, final int txCount) {
TransactionStream transactions = new TransactionStream() {
@Override
public void accept(Visitor<CommittedTransactionRepresentation, Exception> visitor) throws Exception {
for (int i = 1; i <= txCount; i++) {
CommittedTransactionRepresentation transaction = createTransaction(TransactionIdStore.BASE_TX_ID + i);
visitor.visit(transaction);
}
}
};
return new TransactionStreamResponse<>(responseToSendBack, storeIdToRespondWith, transactions, ResourceReleaser.NO_OP);
}
use of org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation in project neo4j by neo4j.
the class DefaultRecoverySPI method startRecovery.
@Override
public Visitor<CommittedTransactionRepresentation, Exception> startRecovery() {
// Calling this method means that recovery is required, tell storage engine about it
// This method will be called before recovery actually starts and so will ensure that
// each store is aware that recovery will be performed. At this point all the stores have
// already started btw.
// Go and read more at {@link CommonAbstractStore#deleteIdGenerator()}
storageEngine.prepareForRecoveryRequired();
transactionsToApply = new TransactionQueue(10_000, (first, last) -> storageEngine.apply(first, RECOVERY));
recoveryVisitor = new RecoveryVisitor(transactionsToApply);
return recoveryVisitor;
}
use of org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation in project neo4j by neo4j.
the class Recovery method init.
@Override
public void init() throws Throwable {
LogPosition recoveryFromPosition = spi.getPositionToRecoverFrom();
if (LogPosition.UNSPECIFIED.equals(recoveryFromPosition)) {
return;
}
monitor.recoveryRequired(recoveryFromPosition);
LogPosition recoveryToPosition;
CommittedTransactionRepresentation lastTransaction = null;
Visitor<CommittedTransactionRepresentation, Exception> recoveryVisitor = spi.startRecovery();
try (TransactionCursor transactionsToRecover = spi.getTransactions(recoveryFromPosition)) {
while (transactionsToRecover.next()) {
lastTransaction = transactionsToRecover.get();
long txId = lastTransaction.getCommitEntry().getTxId();
recoveryVisitor.visit(lastTransaction);
monitor.transactionRecovered(txId);
numberOfRecoveredTransactions++;
}
recoveryToPosition = transactionsToRecover.position();
}
if (recoveryToPosition.equals(LogPosition.UNSPECIFIED)) {
recoveryToPosition = recoveryFromPosition;
}
spi.allTransactionsRecovered(lastTransaction, recoveryToPosition);
recoveredLog = true;
spi.forceEverything();
}
Aggregations