use of com.twitter.util.Promise in project distributedlog by twitter.
the class TestZKLogSegmentMetadataStore method testStoreMaxLogSegmentSequenceNumberOnNonExistentPath.
@Test(timeout = 60000)
public void testStoreMaxLogSegmentSequenceNumberOnNonExistentPath() throws Exception {
Transaction<Object> updateTxn = lsmStore.transaction();
Versioned<Long> value = new Versioned<Long>(999L, new ZkVersion(10));
final Promise<Version> result = new Promise<Version>();
String nonExistentPath = rootZkPath + "/non-existent";
lsmStore.storeMaxLogSegmentSequenceNumber(updateTxn, nonExistentPath, value, new Transaction.OpListener<Version>() {
@Override
public void onCommit(Version r) {
result.setValue(r);
}
@Override
public void onAbort(Throwable t) {
result.setException(t);
}
});
try {
FutureUtils.result(updateTxn.execute());
fail("Should fail on storing log segment sequence number if path doesn't exist");
} catch (ZKException zke) {
assertEquals(KeeperException.Code.NONODE, zke.getKeeperExceptionCode());
}
try {
Await.result(result);
fail("Should fail on storing log segment sequence number if path doesn't exist");
} catch (KeeperException ke) {
assertEquals(KeeperException.Code.NONODE, ke.code());
}
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class TestZKLogSegmentMetadataStore method testStoreMaxLogSegmentSequenceNumber.
@Test(timeout = 60000)
public void testStoreMaxLogSegmentSequenceNumber() throws Exception {
Transaction<Object> updateTxn = lsmStore.transaction();
Versioned<Long> value = new Versioned<Long>(999L, new ZkVersion(0));
final Promise<Version> result = new Promise<Version>();
lsmStore.storeMaxLogSegmentSequenceNumber(updateTxn, rootZkPath, value, new Transaction.OpListener<Version>() {
@Override
public void onCommit(Version r) {
result.setValue(r);
}
@Override
public void onAbort(Throwable t) {
result.setException(t);
}
});
FutureUtils.result(updateTxn.execute());
assertEquals(1, ((ZkVersion) FutureUtils.result(result)).getZnodeVersion());
Stat stat = new Stat();
byte[] data = zkc.get().getData(rootZkPath, false, stat);
assertEquals(999L, DLUtils.deserializeLogSegmentSequenceNumber(data));
assertEquals(1, stat.getVersion());
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class LedgerAllocatorPool method tryObtain.
@Override
public Future<LedgerHandle> tryObtain(final Transaction<Object> txn, final Transaction.OpListener<LedgerHandle> listener) {
final SimpleLedgerAllocator allocator;
synchronized (this) {
if (allocatingList.isEmpty()) {
return Future.exception(new IOException("No ledger allocator available under " + poolPath + "."));
} else {
allocator = allocatingList.removeFirst();
}
}
final Promise<LedgerHandle> tryObtainPromise = new Promise<LedgerHandle>();
final FutureEventListener<LedgerHandle> tryObtainListener = new FutureEventListener<LedgerHandle>() {
@Override
public void onSuccess(LedgerHandle lh) {
synchronized (LedgerAllocatorPool.this) {
obtainMap.put(lh, allocator);
reverseObtainMap.put(allocator, lh);
tryObtainPromise.setValue(lh);
}
}
@Override
public void onFailure(Throwable cause) {
try {
rescueAllocator(allocator);
} catch (IOException ioe) {
logger.info("Failed to rescue allocator {}", allocator.allocatePath, ioe);
}
tryObtainPromise.setException(cause);
}
};
allocator.tryObtain(txn, new Transaction.OpListener<LedgerHandle>() {
@Override
public void onCommit(LedgerHandle lh) {
confirmObtain(allocator);
listener.onCommit(lh);
}
@Override
public void onAbort(Throwable t) {
abortObtain(allocator);
listener.onAbort(t);
}
}).addEventListener(tryObtainListener);
return tryObtainPromise;
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class ReadUtils method asyncReadRecordFromEntries.
/**
* Read record from a given range of ledger entries.
*
* @param streamName
* fully qualified stream name (used for logging)
* @param ledgerDescriptor
* ledger descriptor.
* @param handleCache
* ledger handle cache.
* @param executorService
* executor service used for processing entries
* @param context
* scan context
* @return a future with the log record.
*/
private static Future<LogRecordWithDLSN> asyncReadRecordFromEntries(final String streamName, final LedgerDescriptor ledgerDescriptor, LedgerHandleCache handleCache, final LogSegmentMetadata metadata, final ExecutorService executorService, final ScanContext context, final LogRecordSelector selector) {
final Promise<LogRecordWithDLSN> promise = new Promise<LogRecordWithDLSN>();
final long startEntryId = context.curStartEntryId.get();
final long endEntryId = context.curEndEntryId.get();
if (LOG.isDebugEnabled()) {
LOG.debug("{} reading entries [{} - {}] from {}.", new Object[] { streamName, startEntryId, endEntryId, ledgerDescriptor });
}
FutureEventListener<Enumeration<LedgerEntry>> readEntriesListener = new FutureEventListener<Enumeration<LedgerEntry>>() {
@Override
public void onSuccess(final Enumeration<LedgerEntry> entries) {
if (LOG.isDebugEnabled()) {
LOG.debug("{} finished reading entries [{} - {}] from {}", new Object[] { streamName, startEntryId, endEntryId, ledgerDescriptor });
}
LogRecordWithDLSN record = null;
while (entries.hasMoreElements()) {
LedgerEntry entry = entries.nextElement();
try {
visitEntryRecords(streamName, metadata, ledgerDescriptor.getLogSegmentSequenceNo(), entry, context, selector);
} catch (IOException ioe) {
// exception is only thrown due to bad ledger entry, so it might be corrupted
// we shouldn't do anything beyond this point. throw the exception to application
promise.setException(ioe);
return;
}
}
record = selector.result();
if (LOG.isDebugEnabled()) {
LOG.debug("{} got record from entries [{} - {}] of {} : {}", new Object[] { streamName, startEntryId, endEntryId, ledgerDescriptor, record });
}
promise.setValue(record);
}
@Override
public void onFailure(final Throwable cause) {
String errMsg = "Error reading entries [" + startEntryId + "-" + endEntryId + "] for reading record of " + streamName;
promise.setException(new IOException(errMsg, BKException.create(FutureUtils.bkResultCode(cause))));
}
};
handleCache.asyncReadEntries(ledgerDescriptor, startEntryId, endEntryId).addEventListener(FutureEventListenerRunnable.of(readEntriesListener, executorService));
return promise;
}
use of com.twitter.util.Promise in project distributedlog by twitter.
the class ZKSubscriptionStateStore method getLastCommitPositionFromZK.
Future<DLSN> getLastCommitPositionFromZK() {
final Promise<DLSN> result = new Promise<DLSN>();
try {
logger.debug("Reading last commit position from path {}", zkPath);
zooKeeperClient.get().getData(zkPath, false, new AsyncCallback.DataCallback() {
@Override
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
logger.debug("Read last commit position from path {}: rc = {}", zkPath, rc);
if (KeeperException.Code.NONODE.intValue() == rc) {
result.setValue(DLSN.NonInclusiveLowerBound);
} else if (KeeperException.Code.OK.intValue() != rc) {
result.setException(KeeperException.create(KeeperException.Code.get(rc), path));
} else {
try {
DLSN dlsn = DLSN.deserialize(new String(data, Charsets.UTF_8));
result.setValue(dlsn);
} catch (Exception t) {
logger.warn("Invalid last commit position found from path {}", zkPath, t);
// invalid dlsn recorded in subscription state store
result.setValue(DLSN.NonInclusiveLowerBound);
}
}
}
}, null);
} catch (ZooKeeperClient.ZooKeeperConnectionException zkce) {
result.setException(zkce);
} catch (InterruptedException ie) {
result.setException(new DLInterruptedException("getLastCommitPosition was interrupted", ie));
}
return result;
}
Aggregations