use of com.twitter.util.Future in project distributedlog by twitter.
the class TestDistributedLogService method testCloseStreamsShouldFlush.
@Test(timeout = 60000)
public void testCloseStreamsShouldFlush() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setOutputBufferSize(Integer.MAX_VALUE).setImmediateFlushEnabled(false).setPeriodicFlushFrequencyMilliSeconds(0);
String streamNamePrefix = testName.getMethodName();
DistributedLogServiceImpl localService = createService(serverConf, confLocal);
StreamManagerImpl streamManager = (StreamManagerImpl) localService.getStreamManager();
int numStreams = 10;
int numWrites = 10;
List<Future<WriteResponse>> futureList = Lists.newArrayListWithExpectedSize(numStreams * numWrites);
for (int i = 0; i < numStreams; i++) {
String streamName = streamNamePrefix + "-" + i;
HeartbeatOptions hbOptions = new HeartbeatOptions();
hbOptions.setSendHeartBeatToReader(true);
// make sure the first log segment of each stream created
FutureUtils.result(localService.heartbeatWithOptions(streamName, new WriteContext(), hbOptions));
for (int j = 0; j < numWrites; j++) {
futureList.add(localService.write(streamName, createRecord(i * numWrites + j)));
}
}
assertEquals("There should be " + numStreams + " streams in cache", numStreams, streamManager.getCachedStreams().size());
while (streamManager.getAcquiredStreams().size() < numStreams) {
TimeUnit.MILLISECONDS.sleep(20);
}
Future<List<Void>> closeResult = localService.closeStreams();
List<Void> closedStreams = Await.result(closeResult);
assertEquals("There should be " + numStreams + " streams closed", numStreams, closedStreams.size());
// all writes should be flushed
for (Future<WriteResponse> future : futureList) {
WriteResponse response = Await.result(future);
assertTrue("Op should succeed or be rejected : " + response.getHeader().getCode(), StatusCode.SUCCESS == response.getHeader().getCode() || StatusCode.WRITE_EXCEPTION == response.getHeader().getCode() || StatusCode.STREAM_UNAVAILABLE == response.getHeader().getCode());
}
assertTrue("There should be no streams in the cache", streamManager.getCachedStreams().isEmpty());
assertTrue("There should be no streams in the acquired cache", streamManager.getAcquiredStreams().isEmpty());
localService.shutdown();
}
use of com.twitter.util.Future in project distributedlog by twitter.
the class TestDistributedLogService method testNonDurableWrite.
@Test(timeout = 60000)
public void testNonDurableWrite() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setOutputBufferSize(Integer.MAX_VALUE).setImmediateFlushEnabled(false).setPeriodicFlushFrequencyMilliSeconds(0).setDurableWriteEnabled(false);
ServerConfiguration serverConfLocal = new ServerConfiguration();
serverConfLocal.addConfiguration(serverConf);
serverConfLocal.enableDurableWrite(false);
serverConfLocal.setServiceTimeoutMs(Integer.MAX_VALUE).setStreamProbationTimeoutMs(Integer.MAX_VALUE);
String streamName = testName.getMethodName();
DistributedLogServiceImpl localService = createService(serverConfLocal, confLocal);
StreamManagerImpl streamManager = (StreamManagerImpl) localService.getStreamManager();
int numWrites = 10;
List<Future<WriteResponse>> futureList = new ArrayList<Future<WriteResponse>>();
for (int i = 0; i < numWrites; i++) {
futureList.add(localService.write(streamName, createRecord(i)));
}
assertTrue("Stream " + streamName + " should be cached", streamManager.getCachedStreams().containsKey(streamName));
List<WriteResponse> resultList = FutureUtils.result(Future.collect(futureList));
for (WriteResponse wr : resultList) {
assertEquals(DLSN.InvalidDLSN, DLSN.deserialize(wr.getDlsn()));
}
localService.shutdown();
}
use of com.twitter.util.Future in project distributedlog by twitter.
the class TestDistributedLogService method testCloseStreamsShouldAbort.
@Test(timeout = 60000)
public void testCloseStreamsShouldAbort() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setOutputBufferSize(Integer.MAX_VALUE).setImmediateFlushEnabled(false).setPeriodicFlushFrequencyMilliSeconds(0);
String streamNamePrefix = testName.getMethodName();
DistributedLogServiceImpl localService = createService(serverConf, confLocal);
StreamManagerImpl streamManager = (StreamManagerImpl) localService.getStreamManager();
int numStreams = 10;
int numWrites = 10;
List<Future<WriteResponse>> futureList = Lists.newArrayListWithExpectedSize(numStreams * numWrites);
for (int i = 0; i < numStreams; i++) {
String streamName = streamNamePrefix + "-" + i;
HeartbeatOptions hbOptions = new HeartbeatOptions();
hbOptions.setSendHeartBeatToReader(true);
// make sure the first log segment of each stream created
FutureUtils.result(localService.heartbeatWithOptions(streamName, new WriteContext(), hbOptions));
for (int j = 0; j < numWrites; j++) {
futureList.add(localService.write(streamName, createRecord(i * numWrites + j)));
}
}
assertEquals("There should be " + numStreams + " streams in cache", numStreams, streamManager.getCachedStreams().size());
while (streamManager.getAcquiredStreams().size() < numStreams) {
TimeUnit.MILLISECONDS.sleep(20);
}
for (Stream s : streamManager.getAcquiredStreams().values()) {
StreamImpl stream = (StreamImpl) s;
stream.setStatus(StreamStatus.FAILED);
}
Future<List<Void>> closeResult = localService.closeStreams();
List<Void> closedStreams = Await.result(closeResult);
assertEquals("There should be " + numStreams + " streams closed", numStreams, closedStreams.size());
// all writes should be flushed
for (Future<WriteResponse> future : futureList) {
WriteResponse response = Await.result(future);
assertTrue("Op should fail with " + StatusCode.BK_TRANSMIT_ERROR + " or be rejected : " + response.getHeader().getCode(), StatusCode.BK_TRANSMIT_ERROR == response.getHeader().getCode() || StatusCode.WRITE_EXCEPTION == response.getHeader().getCode() || StatusCode.WRITE_CANCELLED_EXCEPTION == response.getHeader().getCode());
}
// acquired streams should all been removed after we close them
assertTrue("There should be no streams in the acquired cache", streamManager.getAcquiredStreams().isEmpty());
localService.shutdown();
// cached streams wouldn't be removed immediately after streams are closed
// but they should be removed after we shutdown the service
assertTrue("There should be no streams in the cache after shutting down the service", streamManager.getCachedStreams().isEmpty());
}
use of com.twitter.util.Future in project distributedlog by twitter.
the class TestAsyncReaderWriter method testOutstandingWriteLimitBlockAllLimitWithDarkmode.
@Test(timeout = 60000)
public void testOutstandingWriteLimitBlockAllLimitWithDarkmode() throws Exception {
DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
confLocal.addConfiguration(testConf);
confLocal.setOutputBufferSize(0);
confLocal.setImmediateFlushEnabled(true);
confLocal.setPerWriterOutstandingWriteLimit(0);
confLocal.setOutstandingWriteLimitDarkmode(true);
DistributedLogManager dlm = createNewDLM(confLocal, runtime.getMethodName());
BKAsyncLogWriter writer = (BKAsyncLogWriter) (dlm.startAsyncLogSegmentNonPartitioned());
ArrayList<Future<DLSN>> results = new ArrayList<Future<DLSN>>(1000);
for (int i = 0; i < 1000; i++) {
results.add(writer.write(DLMTestUtil.getLogRecordInstance(1L)));
}
for (Future<DLSN> result : results) {
Await.result(result);
}
writer.closeAndComplete();
dlm.close();
}
use of com.twitter.util.Future in project distributedlog by twitter.
the class TestBKLogSegmentWriter method testCloseShouldFlush.
/**
* Close a segment log writer should flush buffered data.
*
* @throws Exception
*/
@Test(timeout = 60000)
public void testCloseShouldFlush() 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
closeWriterAndLock(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 become " + (numRecords - 1), numRecords - 1, writer.getLastTxIdAcknowledged());
assertEquals("Position should still be " + numRecords, 10, writer.getPositionWithinLogSegment());
List<DLSN> dlsns = Await.result(Future.collect(futureList));
assertEquals("All records should be written", numRecords, dlsns.size());
for (int i = 0; i < numRecords; i++) {
DLSN dlsn = dlsns.get(i);
assertEquals("Incorrent ledger sequence number", 0L, dlsn.getLogSegmentSequenceNo());
assertEquals("Incorrent entry id", 0L, dlsn.getEntryId());
assertEquals("Inconsistent slot id", i, dlsn.getSlotId());
}
assertEquals("Last DLSN should be " + dlsns.get(dlsns.size() - 1), dlsns.get(dlsns.size() - 1), writer.getLastDLSN());
LedgerHandle lh = getLedgerHandle(writer);
LedgerHandle readLh = openLedgerNoRecovery(lh);
assertTrue("Ledger " + lh.getId() + " should be closed", readLh.isClosed());
assertEquals("There should be two entries in ledger " + lh.getId(), 1L, readLh.getLastAddConfirmed());
}
Aggregations