use of scala.runtime.BoxedUnit in project distributedlog by twitter.
the class StreamImpl method scheduleTimeout.
void scheduleTimeout(final StreamOp op) {
final Timeout timeout = requestTimer.newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
if (!timeout.isCancelled()) {
serviceTimeout.inc();
handleServiceTimeout("Operation " + op.getClass().getName() + " timeout");
}
}
}, serviceTimeoutMs, TimeUnit.MILLISECONDS);
op.responseHeader().ensure(new Function0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
timeout.cancel();
return null;
}
});
}
use of scala.runtime.BoxedUnit in project distributedlog by twitter.
the class ZKSessionLock method asyncTryLock.
@Override
public Future<LockWaiter> asyncTryLock(final long timeout, final TimeUnit unit) {
final Promise<String> result = new Promise<String>();
final boolean wait = DistributedLogConstants.LOCK_IMMEDIATE != timeout;
if (wait) {
asyncTryLock(wait, result);
} else {
// try to check locks first
zk.getChildren(lockPath, null, new AsyncCallback.Children2Callback() {
@Override
public void processResult(final int rc, String path, Object ctx, final List<String> children, Stat stat) {
lockStateExecutor.submit(lockPath, new SafeRunnable() {
@Override
public void safeRun() {
if (!lockState.inState(State.INIT)) {
result.setException(new LockStateChangedException(lockPath, lockId, State.INIT, lockState.getState()));
return;
}
if (KeeperException.Code.OK.intValue() != rc) {
result.setException(KeeperException.create(KeeperException.Code.get(rc)));
return;
}
FailpointUtils.checkFailPointNoThrow(FailpointUtils.FailPointName.FP_LockTryAcquire);
Collections.sort(children, MEMBER_COMPARATOR);
if (children.size() > 0) {
asyncParseClientID(zk, lockPath, children.get(0)).addEventListener(new FutureEventListener<Pair<String, Long>>() {
@Override
public void onSuccess(Pair<String, Long> owner) {
if (!checkOrClaimLockOwner(owner, result)) {
acquireFuture.updateIfEmpty(new Return<Boolean>(false));
}
}
@Override
public void onFailure(final Throwable cause) {
lockStateExecutor.submit(lockPath, new SafeRunnable() {
@Override
public void safeRun() {
result.setException(cause);
}
});
}
});
} else {
asyncTryLock(wait, result);
}
}
});
}
}, null);
}
final Promise<Boolean> waiterAcquireFuture = new Promise<Boolean>(new com.twitter.util.Function<Throwable, BoxedUnit>() {
@Override
public BoxedUnit apply(Throwable t) {
acquireFuture.raise(t);
return BoxedUnit.UNIT;
}
});
return result.map(new AbstractFunction1<String, LockWaiter>() {
@Override
public LockWaiter apply(final String currentOwner) {
final Exception acquireException = new OwnershipAcquireFailedException(lockPath, currentOwner);
FutureUtils.within(acquireFuture, timeout, unit, acquireException, lockStateExecutor, lockPath).addEventListener(new FutureEventListener<Boolean>() {
@Override
public void onSuccess(Boolean acquired) {
completeOrFail(acquireException);
}
@Override
public void onFailure(final Throwable acquireCause) {
completeOrFail(acquireException);
}
private void completeOrFail(final Throwable acquireCause) {
if (isLockHeld()) {
waiterAcquireFuture.setValue(true);
} else {
asyncUnlock().addEventListener(new FutureEventListener<BoxedUnit>() {
@Override
public void onSuccess(BoxedUnit value) {
waiterAcquireFuture.setException(acquireCause);
}
@Override
public void onFailure(Throwable cause) {
waiterAcquireFuture.setException(acquireCause);
}
});
}
}
});
;
return new LockWaiter(lockId.getLeft(), currentOwner, waiterAcquireFuture);
}
});
}
use of scala.runtime.BoxedUnit in project distributedlog by twitter.
the class ZKSessionLock method asyncUnlock.
Future<BoxedUnit> asyncUnlock(final Throwable cause) {
final Promise<BoxedUnit> promise = new Promise<BoxedUnit>();
// Use lock executor here rather than lock action, because we want this opertaion to be applied
// whether the epoch has changed or not. The member node is EPHEMERAL_SEQUENTIAL so there's no
// risk of an ABA problem where we delete and recreate a node and then delete it again here.
lockStateExecutor.submit(lockPath, new SafeRunnable() {
@Override
public void safeRun() {
acquireFuture.updateIfEmpty(new Throw<Boolean>(cause));
unlockInternal(promise);
promise.addEventListener(new OpStatsListener<BoxedUnit>(unlockStats));
}
});
return promise;
}
use of scala.runtime.BoxedUnit in project distributedlog by twitter.
the class TestZKSessionLock method testExecuteLockAction.
@Test(timeout = 60000)
public void testExecuteLockAction() throws Exception {
String lockPath = "/test-execute-lock-action";
String clientId = "test-execute-lock-action-" + System.currentTimeMillis();
ZKSessionLock lock = new ZKSessionLock(zkc, lockPath, clientId, lockStateExecutor);
final AtomicInteger counter = new AtomicInteger(0);
// lock action would be executed in same epoch
final CountDownLatch latch1 = new CountDownLatch(1);
lock.executeLockAction(lock.getEpoch().get(), new LockAction() {
@Override
public void execute() {
counter.incrementAndGet();
latch1.countDown();
}
@Override
public String getActionName() {
return "increment1";
}
});
latch1.await();
assertEquals("counter should be increased in same epoch", 1, counter.get());
// lock action would not be executed in same epoch
final CountDownLatch latch2 = new CountDownLatch(1);
lock.executeLockAction(lock.getEpoch().get() + 1, new LockAction() {
@Override
public void execute() {
counter.incrementAndGet();
}
@Override
public String getActionName() {
return "increment2";
}
});
lock.executeLockAction(lock.getEpoch().get(), new LockAction() {
@Override
public void execute() {
latch2.countDown();
}
@Override
public String getActionName() {
return "countdown";
}
});
latch2.await();
assertEquals("counter should not be increased in different epochs", 1, counter.get());
// lock action would not be executed in same epoch and promise would be satisfied with exception
Promise<BoxedUnit> promise = new Promise<BoxedUnit>();
lock.executeLockAction(lock.getEpoch().get() + 1, new LockAction() {
@Override
public void execute() {
counter.incrementAndGet();
}
@Override
public String getActionName() {
return "increment3";
}
}, promise);
try {
Await.result(promise);
fail("Should satisfy promise with epoch changed exception.");
} catch (EpochChangedException ece) {
// expected
}
assertEquals("counter should not be increased in different epochs", 1, counter.get());
lockStateExecutor.shutdown();
}
use of scala.runtime.BoxedUnit 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