use of com.twitter.util.Promise in project distributedlog by twitter.
the class TestEntry method testWriteRecords.
@Test(timeout = 20000)
public void testWriteRecords() throws Exception {
Writer writer = Entry.newEntry("test-write-records", 1024, true, CompressionCodec.Type.NONE, NullStatsLogger.INSTANCE);
assertEquals("zero bytes", 0, writer.getNumBytes());
assertEquals("zero records", 0, writer.getNumRecords());
List<Future<DLSN>> writePromiseList = Lists.newArrayList();
// write first 5 records
for (int i = 0; i < 5; i++) {
LogRecord record = new LogRecord(i, ("record-" + i).getBytes(UTF_8));
record.setPositionWithinLogSegment(i);
Promise<DLSN> writePromise = new Promise<DLSN>();
writer.writeRecord(record, writePromise);
writePromiseList.add(writePromise);
assertEquals((i + 1) + " records", (i + 1), writer.getNumRecords());
}
// write large record
LogRecord largeRecord = new LogRecord(1L, new byte[MAX_LOGRECORD_SIZE + 1]);
try {
writer.writeRecord(largeRecord, new Promise<DLSN>());
Assert.fail("Should fail on writing large record");
} catch (LogRecordTooLongException lrtle) {
// expected
}
assertEquals("5 records", 5, writer.getNumRecords());
// write another 5 records
for (int i = 0; i < 5; i++) {
LogRecord record = new LogRecord(i + 5, ("record-" + (i + 5)).getBytes(UTF_8));
record.setPositionWithinLogSegment(i + 5);
Promise<DLSN> writePromise = new Promise<DLSN>();
writer.writeRecord(record, writePromise);
writePromiseList.add(writePromise);
assertEquals((i + 6) + " records", (i + 6), writer.getNumRecords());
}
Buffer buffer = writer.getBuffer();
// Test transmit complete
writer.completeTransmit(1L, 1L);
List<DLSN> writeResults = Await.result(Future.collect(writePromiseList));
for (int i = 0; i < 10; i++) {
Assert.assertEquals(new DLSN(1L, 1L, i), writeResults.get(i));
}
// Test reading from buffer
Entry recordSet = Entry.newBuilder().setData(buffer.getData(), 0, buffer.size()).setLogSegmentInfo(1L, 1L).setEntryId(0L).build();
Reader reader = recordSet.reader();
LogRecordWithDLSN record = reader.nextRecord();
int numReads = 0;
long expectedTxid = 0L;
while (null != record) {
Assert.assertEquals(expectedTxid, record.getTransactionId());
Assert.assertEquals(expectedTxid, record.getSequenceId());
Assert.assertEquals(new DLSN(1L, 0L, expectedTxid), record.getDlsn());
++numReads;
++expectedTxid;
record = reader.nextRecord();
}
Assert.assertEquals(10, numReads);
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class Utils method zkSetData.
/**
* Set <code>data</code> to zookeeper <code>path</code>.
*
* @param zk
* zookeeper client
* @param path
* path to set data
* @param data
* data to set
* @param version
* version used to set data
* @return future representing the version after this operation.
*/
public static Future<ZkVersion> zkSetData(ZooKeeper zk, String path, byte[] data, ZkVersion version) {
final Promise<ZkVersion> promise = new Promise<ZkVersion>();
zk.setData(path, data, version.getZnodeVersion(), new AsyncCallback.StatCallback() {
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
if (KeeperException.Code.OK.intValue() == rc) {
promise.updateIfEmpty(new Return<ZkVersion>(new ZkVersion(stat.getVersion())));
return;
}
promise.updateIfEmpty(new Throw<ZkVersion>(KeeperException.create(KeeperException.Code.get(rc))));
return;
}
}, null);
return promise;
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class BKLogHandler method asyncGetFirstLogRecord.
public Future<LogRecordWithDLSN> asyncGetFirstLogRecord() {
final Promise<LogRecordWithDLSN> promise = new Promise<LogRecordWithDLSN>();
checkLogStreamExistsAsync().addEventListener(new FutureEventListener<Void>() {
@Override
public void onSuccess(Void value) {
asyncGetFullLedgerList(true, true).addEventListener(new FutureEventListener<List<LogSegmentMetadata>>() {
@Override
public void onSuccess(List<LogSegmentMetadata> ledgerList) {
if (ledgerList.isEmpty()) {
promise.setException(new LogEmptyException("Log " + getFullyQualifiedName() + " has no records"));
return;
}
Future<LogRecordWithDLSN> firstRecord = null;
for (LogSegmentMetadata ledger : ledgerList) {
if (!ledger.isTruncated() && (ledger.getRecordCount() > 0 || ledger.isInProgress())) {
firstRecord = asyncReadFirstUserRecord(ledger, DLSN.InitialDLSN);
break;
}
}
if (null != firstRecord) {
promise.become(firstRecord);
} else {
promise.setException(new LogEmptyException("Log " + getFullyQualifiedName() + " has no records"));
}
}
@Override
public void onFailure(Throwable cause) {
promise.setException(cause);
}
});
}
@Override
public void onFailure(Throwable cause) {
promise.setException(cause);
}
});
return promise;
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class BKLogHandler method checkLogStreamExistsAsync.
Future<Void> checkLogStreamExistsAsync() {
final Promise<Void> promise = new Promise<Void>();
try {
final ZooKeeper zk = zooKeeperClient.get();
zk.sync(logMetadata.getLogSegmentsPath(), new AsyncCallback.VoidCallback() {
@Override
public void processResult(int syncRc, String path, Object syncCtx) {
if (KeeperException.Code.NONODE.intValue() == syncRc) {
promise.setException(new LogNotFoundException(String.format("Log %s does not exist or has been deleted", getFullyQualifiedName())));
return;
} else if (KeeperException.Code.OK.intValue() != syncRc) {
promise.setException(new ZKException("Error on checking log existence for " + getFullyQualifiedName(), KeeperException.create(KeeperException.Code.get(syncRc))));
return;
}
zk.exists(logMetadata.getLogSegmentsPath(), false, new AsyncCallback.StatCallback() {
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
if (KeeperException.Code.OK.intValue() == rc) {
promise.setValue(null);
} else if (KeeperException.Code.NONODE.intValue() == rc) {
promise.setException(new LogNotFoundException(String.format("Log %s does not exist or has been deleted", getFullyQualifiedName())));
} else {
promise.setException(new ZKException("Error on checking log existence for " + getFullyQualifiedName(), KeeperException.create(KeeperException.Code.get(rc))));
}
}
}, null);
}
}, null);
} catch (InterruptedException ie) {
LOG.error("Interrupted while reading {}", logMetadata.getLogSegmentsPath(), ie);
promise.setException(new DLInterruptedException("Interrupted while checking " + logMetadata.getLogSegmentsPath(), ie));
} catch (ZooKeeperClient.ZooKeeperConnectionException e) {
promise.setException(e);
}
return promise;
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class BKLogHandler method asyncGetLedgerList.
protected Future<List<LogSegmentMetadata>> asyncGetLedgerList(final boolean forceFetch, final boolean fetchFullList, final Comparator<LogSegmentMetadata> comparator, final boolean throwOnEmpty) {
final Promise<List<LogSegmentMetadata>> promise = new Promise<List<LogSegmentMetadata>>();
final Stopwatch stopwatch = Stopwatch.createStarted();
final OpStatsLogger statsLogger = fetchFullList ? getFullListStat : getFilteredListStat;
asyncDoGetLedgerList(forceFetch, fetchFullList, comparator, throwOnEmpty).addEventListener(new FutureEventListener<List<LogSegmentMetadata>>() {
@Override
public void onSuccess(List<LogSegmentMetadata> value) {
statsLogger.registerSuccessfulEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
promise.setValue(value);
}
@Override
public void onFailure(Throwable cause) {
statsLogger.registerFailedEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
promise.setException(cause);
}
});
return promise;
}
Aggregations