use of com.twitter.util.ExceptionalFunction in project distributedlog by twitter.
the class BKLogReadHandler method lockStream.
/**
* Elective stream lock--readers are not required to acquire the lock before using the stream.
*/
synchronized Future<Void> lockStream() {
if (null == lockAcquireFuture) {
final Function0<DistributedLock> lockFunction = new ExceptionalFunction0<DistributedLock>() {
@Override
public DistributedLock applyE() throws IOException {
// Unfortunately this has a blocking call which we should not execute on the
// ZK completion thread
BKLogReadHandler.this.readLock = new ZKDistributedLock(lockStateExecutor, lockFactory, readLockPath, conf.getLockTimeoutMilliSeconds(), statsLogger.scope("read_lock"));
LOG.info("acquiring readlock {} at {}", getLockClientId(), readLockPath);
return BKLogReadHandler.this.readLock;
}
};
lockAcquireFuture = ensureReadLockPathExist().flatMap(new ExceptionalFunction<Void, Future<Void>>() {
@Override
public Future<Void> applyE(Void in) throws Throwable {
return scheduler.apply(lockFunction).flatMap(new ExceptionalFunction<DistributedLock, Future<Void>>() {
@Override
public Future<Void> applyE(DistributedLock lock) throws IOException {
return acquireLockOnExecutorThread(lock);
}
});
}
});
}
return lockAcquireFuture;
}
use of com.twitter.util.ExceptionalFunction in project distributedlog by twitter.
the class BKDistributedLogManager method getAsyncLogReaderWithLock.
protected Future<AsyncLogReader> getAsyncLogReaderWithLock(final Optional<DLSN> fromDLSN, final Optional<String> subscriberId) {
if (!fromDLSN.isPresent() && !subscriberId.isPresent()) {
return Future.exception(new UnexpectedException("Neither from dlsn nor subscriber id is provided."));
}
final BKAsyncLogReaderDLSN reader = new BKAsyncLogReaderDLSN(BKDistributedLogManager.this, scheduler, getLockStateExecutor(true), fromDLSN.isPresent() ? fromDLSN.get() : DLSN.InitialDLSN, subscriberId, false, dynConf.getDeserializeRecordSetOnReads(), statsLogger);
pendingReaders.add(reader);
final Future<Void> lockFuture = reader.lockStream();
final Promise<AsyncLogReader> createPromise = new Promise<AsyncLogReader>(new Function<Throwable, BoxedUnit>() {
@Override
public BoxedUnit apply(Throwable cause) {
// cancel the lock when the creation future is cancelled
lockFuture.cancel();
return BoxedUnit.UNIT;
}
});
// lock the stream - fetch the last commit position on success
lockFuture.flatMap(new Function<Void, Future<AsyncLogReader>>() {
@Override
public Future<AsyncLogReader> apply(Void complete) {
if (fromDLSN.isPresent()) {
return Future.value((AsyncLogReader) reader);
}
LOG.info("Reader {} @ {} reading last commit position from subscription store after acquired lock.", subscriberId.get(), name);
// we acquired lock
final SubscriptionStateStore stateStore = getSubscriptionStateStore(subscriberId.get());
return stateStore.getLastCommitPosition().map(new ExceptionalFunction<DLSN, AsyncLogReader>() {
@Override
public AsyncLogReader applyE(DLSN lastCommitPosition) throws UnexpectedException {
LOG.info("Reader {} @ {} positioned to last commit position {}.", new Object[] { subscriberId.get(), name, lastCommitPosition });
reader.setStartDLSN(lastCommitPosition);
return reader;
}
});
}
}).addEventListener(new FutureEventListener<AsyncLogReader>() {
@Override
public void onSuccess(AsyncLogReader r) {
pendingReaders.remove(reader);
FutureUtils.setValue(createPromise, r);
}
@Override
public void onFailure(final Throwable cause) {
pendingReaders.remove(reader);
reader.asyncClose().ensure(new AbstractFunction0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
FutureUtils.setException(createPromise, cause);
return BoxedUnit.UNIT;
}
});
}
});
return createPromise;
}
Aggregations