use of com.twitter.distributedlog.exceptions.UnexpectedException in project distributedlog by twitter.
the class TestFederatedZKLogMetadataStore method testDuplicatedLogs.
@Test(timeout = 60000)
public void testDuplicatedLogs() throws Exception {
DistributedLogConfiguration conf = new DistributedLogConfiguration();
conf.addConfiguration(baseConf);
String logName = "test-log";
FutureUtils.result(metadataStore.createLog(logName));
URI subNs1 = FutureUtils.result(metadataStore.createSubNamespace());
URI subNs2 = FutureUtils.result(metadataStore.createSubNamespace());
String duplicatedLogName = "test-duplicated-logs";
// Create same log in different sub namespaces
metadataStore.createLogInNamespaceSync(subNs1, duplicatedLogName);
metadataStore.createLogInNamespaceSync(subNs2, duplicatedLogName);
try {
FutureUtils.result(metadataStore.createLog("non-existent-log"));
fail("should throw exception when duplicated log found");
} catch (UnexpectedException ue) {
// should throw unexpected exception
assertTrue(metadataStore.duplicatedLogFound.get());
}
try {
FutureUtils.result(metadataStore.getLogLocation(logName));
fail("should throw exception when duplicated log found");
} catch (UnexpectedException ue) {
// should throw unexpected exception
assertTrue(metadataStore.duplicatedLogFound.get());
}
try {
FutureUtils.result(metadataStore.getLogLocation("non-existent-log"));
fail("should throw exception when duplicated log found");
} catch (UnexpectedException ue) {
// should throw unexpected exception
assertTrue(metadataStore.duplicatedLogFound.get());
}
try {
FutureUtils.result(metadataStore.getLogLocation(duplicatedLogName));
fail("should throw exception when duplicated log found");
} catch (UnexpectedException ue) {
// should throw unexpected exception
assertTrue(metadataStore.duplicatedLogFound.get());
}
try {
FutureUtils.result(metadataStore.getLogs());
fail("should throw exception when duplicated log found");
} catch (UnexpectedException ue) {
// should throw unexpected exception
assertTrue(metadataStore.duplicatedLogFound.get());
}
}
use of com.twitter.distributedlog.exceptions.UnexpectedException 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;
}
use of com.twitter.distributedlog.exceptions.UnexpectedException in project distributedlog by twitter.
the class StreamImpl method delete.
@Override
public void delete() throws IOException {
if (null != writer) {
Utils.close(writer);
synchronized (this) {
writer = null;
lastException = new StreamUnavailableException("Stream was deleted");
}
}
if (null == manager) {
throw new UnexpectedException("No stream " + name + " to delete");
}
manager.delete();
}
use of com.twitter.distributedlog.exceptions.UnexpectedException in project distributedlog by twitter.
the class ZKDistributedLock method asyncAcquire.
/**
* Asynchronously acquire the lock. Technically the try phase of this operation--which adds us to the waiter
* list--is executed synchronously, but the lock wait itself doesn't block.
*/
public synchronized Future<ZKDistributedLock> asyncAcquire() {
if (null != lockAcquireFuture) {
return Future.exception(new UnexpectedException("Someone is already acquiring/acquired lock " + lockPath));
}
final Promise<ZKDistributedLock> promise = new Promise<ZKDistributedLock>(new Function<Throwable, BoxedUnit>() {
@Override
public BoxedUnit apply(Throwable cause) {
lockStateExecutor.submit(lockPath, new Runnable() {
@Override
public void run() {
asyncClose();
}
});
return BoxedUnit.UNIT;
}
});
final Stopwatch stopwatch = Stopwatch.createStarted();
promise.addEventListener(new FutureEventListener<ZKDistributedLock>() {
@Override
public void onSuccess(ZKDistributedLock lock) {
acquireStats.registerSuccessfulEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
}
@Override
public void onFailure(Throwable cause) {
acquireStats.registerFailedEvent(stopwatch.stop().elapsed(TimeUnit.MICROSECONDS));
// release the lock if fail to acquire
asyncClose();
}
});
this.lockAcquireFuture = promise;
lockStateExecutor.submit(lockPath, new Runnable() {
@Override
public void run() {
doAsyncAcquireWithSemaphore(promise, lockTimeout);
}
});
return promise;
}
use of com.twitter.distributedlog.exceptions.UnexpectedException in project distributedlog by twitter.
the class ZKSessionLock method processLockWaiters.
/**
* Check Lock Owner Phase 2 : check all lock waiters to get current owner and wait for ownership if necessary.
*
* @param lockWatcher
* lock watcher.
* @param wait
* whether to wait for ownership.
* @param getChildrenRc
* result of getting all lock waiters
* @param children
* current lock waiters.
* @param promise
* promise to satisfy with current lock owner.
*/
private void processLockWaiters(final LockWatcher lockWatcher, final boolean wait, final int getChildrenRc, final List<String> children, final Promise<String> promise) {
executeLockAction(lockWatcher.epoch, new LockAction() {
@Override
public void execute() {
if (!lockState.inState(State.PREPARED)) {
// e.g. lock closed or session expired after prepared
promise.setException(new LockStateChangedException(lockPath, lockId, State.PREPARED, lockState.getState()));
return;
}
if (KeeperException.Code.OK.intValue() != getChildrenRc) {
promise.setException(KeeperException.create(KeeperException.Code.get(getChildrenRc)));
return;
}
if (children.isEmpty()) {
LOG.error("Error, member list is empty for lock {}.", lockPath);
promise.setException(new UnexpectedException("Empty member list for lock " + lockPath));
return;
}
// sort the children
Collections.sort(children, MEMBER_COMPARATOR);
final String cid = currentId;
final int memberIndex = children.indexOf(cid);
if (LOG.isDebugEnabled()) {
LOG.debug("{} is the number {} member in the list.", cid, memberIndex);
}
// If we hold the lock
if (memberIndex == 0) {
LOG.info("{} acquired the lock {}.", cid, lockPath);
claimOwnership(lockWatcher.epoch);
promise.setValue(cid);
} else if (memberIndex > 0) {
// we are in the member list but we didn't hold the lock
// get ownership of current owner
asyncParseClientID(zk, lockPath, children.get(0)).addEventListener(new FutureEventListener<Pair<String, Long>>() {
@Override
public void onSuccess(Pair<String, Long> currentOwner) {
watchLockOwner(lockWatcher, wait, cid, children.get(memberIndex - 1), children.get(0), currentOwner, promise);
}
@Override
public void onFailure(final Throwable cause) {
// ensure promise is satisfied in lock thread
executeLockAction(lockWatcher.epoch, new LockAction() {
@Override
public void execute() {
promise.setException(cause);
}
@Override
public String getActionName() {
return "handleFailureOnParseClientID(lockPath=" + lockPath + ")";
}
}, promise);
}
});
} else {
LOG.error("Member {} doesn't exist in the members list {} for lock {}.", new Object[] { cid, children, lockPath });
promise.setException(new UnexpectedException("Member " + cid + " doesn't exist in member list " + children + " for lock " + lockPath));
}
}
@Override
public String getActionName() {
return "processLockWaiters(rc=" + getChildrenRc + ", waiters=" + children + ")";
}
}, promise);
}
Aggregations