use of org.apache.distributedlog.exceptions.TransactionIdOutOfOrderException in project bookkeeper by apache.
the class BKLogWriteHandler method doStartLogSegment.
protected void doStartLogSegment(final long txId, final boolean bestEffort, final boolean allowMaxTxID, final CompletableFuture<BKLogSegmentWriter> promise) {
// validate the tx id
if ((txId < 0) || (!allowMaxTxID && (txId == DistributedLogConstants.MAX_TXID))) {
FutureUtils.completeExceptionally(promise, new IOException("Invalid Transaction Id " + txId));
return;
}
long highestTxIdWritten = maxTxId.get();
if (txId < highestTxIdWritten) {
if (highestTxIdWritten == DistributedLogConstants.MAX_TXID) {
LOG.error("We've already marked the stream as ended and attempting to start a new log segment");
FutureUtils.completeExceptionally(promise, new EndOfStreamException("Writing to a stream after it has been marked as completed"));
return;
} else {
LOG.error("We've already seen TxId {} the max TXId is {}", txId, highestTxIdWritten);
FutureUtils.completeExceptionally(promise, new TransactionIdOutOfOrderException(txId, highestTxIdWritten));
return;
}
}
try {
logSegmentAllocator.allocate();
} catch (IOException e) {
// failed to issue an allocation request
failStartLogSegment(promise, bestEffort, e);
return;
}
// start the transaction from zookeeper
final Transaction<Object> txn = streamMetadataStore.newTransaction();
// failpoint injected before creating ledger
try {
FailpointUtils.checkFailPoint(FailpointUtils.FailPointName.FP_StartLogSegmentBeforeLedgerCreate);
} catch (IOException ioe) {
failStartLogSegment(promise, bestEffort, ioe);
return;
}
logSegmentAllocator.tryObtain(txn, NULL_OP_LISTENER).whenComplete(new FutureEventListener<LogSegmentEntryWriter>() {
@Override
public void onSuccess(LogSegmentEntryWriter entryWriter) {
// try-obtain succeed
createInprogressLogSegment(txn, txId, entryWriter, bestEffort, promise);
}
@Override
public void onFailure(Throwable cause) {
failStartLogSegment(promise, bestEffort, cause);
}
});
}
use of org.apache.distributedlog.exceptions.TransactionIdOutOfOrderException in project bookkeeper by apache.
the class TestBKDistributedLogManager method testWriteRestartFrom1.
/**
* Create a bkdlm namespace, write a journal from txid 1, close stream.
* Try to create a new journal from txid 1. Should throw an exception.
*/
@Test(timeout = 60000)
public void testWriteRestartFrom1() throws Exception {
DistributedLogManager dlm = createNewDLM(conf, "distrlog-restartFrom1");
long txid = 1;
BKSyncLogWriter out = (BKSyncLogWriter) dlm.startLogSegmentNonPartitioned();
for (long j = 1; j <= DEFAULT_SEGMENT_SIZE; j++) {
LogRecord op = DLMTestUtil.getLogRecordInstance(txid++);
out.write(op);
}
out.closeAndComplete();
txid = 1;
try {
out = (BKSyncLogWriter) dlm.startLogSegmentNonPartitioned();
out.write(DLMTestUtil.getLogRecordInstance(txid));
fail("Shouldn't be able to start another journal from " + txid + " when one already exists");
} catch (Exception ioe) {
LOG.info("Caught exception as expected", ioe);
} finally {
out.close();
}
// test border case
txid = DEFAULT_SEGMENT_SIZE - 1;
try {
out = (BKSyncLogWriter) dlm.startLogSegmentNonPartitioned();
out.write(DLMTestUtil.getLogRecordInstance(txid));
fail("Shouldn't be able to start another journal from " + txid + " when one already exists");
} catch (TransactionIdOutOfOrderException rste) {
LOG.info("Caught exception as expected", rste);
} finally {
out.close();
}
// open journal continuing from before
txid = DEFAULT_SEGMENT_SIZE + 1;
out = (BKSyncLogWriter) dlm.startLogSegmentNonPartitioned();
assertNotNull(out);
for (long j = 1; j <= DEFAULT_SEGMENT_SIZE; j++) {
LogRecord op = DLMTestUtil.getLogRecordInstance(txid++);
out.write(op);
}
out.closeAndComplete();
// open journal arbitarily far in the future
txid = DEFAULT_SEGMENT_SIZE * 4;
out = (BKSyncLogWriter) dlm.startLogSegmentNonPartitioned();
out.write(DLMTestUtil.getLogRecordInstance(txid));
out.close();
dlm.close();
}
Aggregations