use of com.twitter.distributedlog.lock.ZKDistributedLock in project distributedlog by twitter.
the class BKDistributedLogManager method createWriteHandler.
private void createWriteHandler(ZKLogMetadataForWriter logMetadata, boolean lockHandler, final Promise<BKLogWriteHandler> createPromise) {
OrderedScheduler lockStateExecutor = getLockStateExecutor(true);
// Build the locks
DistributedLock lock;
if (conf.isWriteLockEnabled()) {
lock = new ZKDistributedLock(lockStateExecutor, getLockFactory(true), logMetadata.getLockPath(), conf.getLockTimeoutMilliSeconds(), statsLogger);
} else {
lock = NopDistributedLock.INSTANCE;
}
// Build the ledger allocator
LedgerAllocator allocator;
try {
allocator = createLedgerAllocator(logMetadata);
} catch (IOException e) {
FutureUtils.setException(createPromise, e);
return;
}
// Make sure writer handler created before resources are initialized
final BKLogWriteHandler writeHandler = new BKLogWriteHandler(logMetadata, conf, writerZKCBuilder, writerBKCBuilder, writerMetadataStore, scheduler, allocator, statsLogger, perLogStatsLogger, alertStatsLogger, clientId, regionId, writeLimiter, featureProvider, dynConf, lock);
PermitManager manager = getLogSegmentRollingPermitManager();
if (manager instanceof Watcher) {
writeHandler.register((Watcher) manager);
}
if (lockHandler) {
writeHandler.lockHandler().addEventListener(new FutureEventListener<DistributedLock>() {
@Override
public void onSuccess(DistributedLock lock) {
FutureUtils.setValue(createPromise, writeHandler);
}
@Override
public void onFailure(final Throwable cause) {
writeHandler.asyncClose().ensure(new AbstractFunction0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
FutureUtils.setException(createPromise, cause);
return BoxedUnit.UNIT;
}
});
}
});
} else {
FutureUtils.setValue(createPromise, writeHandler);
}
}
use of com.twitter.distributedlog.lock.ZKDistributedLock in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testNondurableWriteAfterEndOfStream.
/**
* Non durable write should fail if writer is marked as end of stream.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testNondurableWriteAfterEndOfStream() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
confLocal.setDurableWriteEnabled(false);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
FutureUtils.result(writer.markEndOfStream());
try {
Await.result(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(1)));
fail("Should fail the write if the writer is marked as end of stream");
} catch (EndOfStreamException we) {
// expected
}
closeWriterAndLock(writer, lock);
}
use of com.twitter.distributedlog.lock.ZKDistributedLock in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testAbortShouldNotFlush.
/**
* Abort a segment log writer should just abort pending writes and not flush buffered data.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testAbortShouldNotFlush() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
// Use another lock to wait for writer releasing lock
ZKDistributedLock lock0 = createLock("/test/lock-" + runtime.getMethodName(), zkc0, false);
Future<ZKDistributedLock> lockFuture0 = lock0.asyncAcquire();
// add 10 records
int numRecords = 10;
List<Future<DLSN>> futureList = new ArrayList<Future<DLSN>>(numRecords);
for (int i = 0; i < numRecords; i++) {
futureList.add(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(i)));
}
assertEquals("Last tx id should be " + (numRecords - 1), numRecords - 1, writer.getLastTxId());
assertEquals("Last acked tx id should be -1", -1L, writer.getLastTxIdAcknowledged());
assertEquals("Last DLSN should be " + DLSN.InvalidDLSN, DLSN.InvalidDLSN, writer.getLastDLSN());
assertEquals("Position should be " + numRecords, 10, writer.getPositionWithinLogSegment());
// close the writer should flush buffered data and release lock
abortWriterAndLock(writer, lock);
Await.result(lockFuture0);
lock0.checkOwnership();
assertEquals("Last tx id should still be " + (numRecords - 1), numRecords - 1, writer.getLastTxId());
assertEquals("Last acked tx id should still be " + (numRecords - 1), -1L, writer.getLastTxIdAcknowledged());
assertEquals("Last DLSN should still be " + DLSN.InvalidDLSN, DLSN.InvalidDLSN, writer.getLastDLSN());
assertEquals("Position should still be " + numRecords, 10, writer.getPositionWithinLogSegment());
for (int i = 0; i < numRecords; i++) {
try {
Await.result(futureList.get(i));
fail("Should be aborted record " + i + " with transmit exception");
} catch (WriteCancelledException wce) {
assertTrue("Record " + i + " should be aborted because of ledger fenced", wce.getCause() instanceof BKTransmitException);
BKTransmitException bkte = (BKTransmitException) wce.getCause();
assertEquals("Record " + i + " should be aborted", BKException.Code.InterruptedException, bkte.getBKResultCode());
}
}
// check no entries were written
LedgerHandle lh = getLedgerHandle(writer);
LedgerHandle readLh = openLedgerNoRecovery(lh);
assertTrue("Ledger " + lh.getId() + " should not be closed", readLh.isClosed());
assertEquals("There should be no entries in ledger " + lh.getId(), LedgerHandle.INVALID_ENTRY_ID, readLh.getLastAddConfirmed());
}
use of com.twitter.distributedlog.lock.ZKDistributedLock in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testNondurableWrite.
/**
* Non durable write should fail if writer is marked as end of stream.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testNondurableWrite() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
confLocal.setDurableWriteEnabled(false);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
assertEquals(DLSN.InvalidDLSN, Await.result(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(2))));
assertEquals(-1L, ((BKLogSegmentEntryWriter) writer.getEntryWriter()).getLedgerHandle().getLastAddPushed());
closeWriterAndLock(writer, lock);
}
use of com.twitter.distributedlog.lock.ZKDistributedLock in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testNondurableWriteAfterWriterIsClosed.
/**
* Non durable write should fail if writer is closed.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testNondurableWriteAfterWriterIsClosed() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setImmediateFlushEnabled(false);
confLocal.setOutputBufferSize(Integer.MAX_VALUE);
confLocal.setPeriodicFlushFrequencyMilliSeconds(0);
confLocal.setDurableWriteEnabled(false);
ZKDistributedLock lock = createLock("/test/lock-" + runtime.getMethodName(), zkc, true);
BKLogSegmentWriter writer = createLogSegmentWriter(confLocal, 0L, -1L, lock);
// close the writer
closeWriterAndLock(writer, lock);
FutureUtils.result(writer.asyncClose());
try {
Await.result(writer.asyncWrite(DLMTestUtil.getLogRecordInstance(1)));
fail("Should fail the write if the writer is closed");
} catch (WriteException we) {
// expected
}
}
Aggregations