use of com.twitter.util.FutureEventListener in project distributedlog by twitter.
the class ZKAccessControlManager method fetchAccessControlEntries.
private void fetchAccessControlEntries(final Promise<Void> promise) {
try {
zkc.get().getChildren(zkRootPath, this, new AsyncCallback.Children2Callback() {
@Override
public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
if (KeeperException.Code.OK.intValue() != rc) {
promise.setException(KeeperException.create(KeeperException.Code.get(rc)));
return;
}
Set<String> streamsReceived = new HashSet<String>();
streamsReceived.addAll(children);
Set<String> streamsCached = streamEntries.keySet();
Set<String> streamsRemoved = Sets.difference(streamsCached, streamsReceived).immutableCopy();
for (String s : streamsRemoved) {
ZKAccessControl accessControl = streamEntries.remove(s);
if (null != accessControl) {
logger.info("Removed Access Control Entry for stream {} : {}", s, accessControl.getAccessControlEntry());
}
}
if (streamsReceived.isEmpty()) {
promise.setValue(null);
return;
}
final AtomicInteger numPendings = new AtomicInteger(streamsReceived.size());
final AtomicInteger numFailures = new AtomicInteger(0);
for (String s : streamsReceived) {
final String streamName = s;
ZKAccessControl.read(zkc, zkRootPath + "/" + streamName, null).addEventListener(new FutureEventListener<ZKAccessControl>() {
@Override
public void onSuccess(ZKAccessControl accessControl) {
streamEntries.put(streamName, accessControl);
logger.info("Added overrided access control for stream {} : {}", streamName, accessControl.getAccessControlEntry());
complete();
}
@Override
public void onFailure(Throwable cause) {
if (cause instanceof KeeperException.NoNodeException) {
streamEntries.remove(streamName);
} else if (cause instanceof ZKAccessControl.CorruptedAccessControlException) {
logger.warn("Access control is corrupted for stream {} @ {}, skipped it ...", new Object[] { streamName, zkRootPath, cause });
streamEntries.remove(streamName);
} else {
if (1 == numFailures.incrementAndGet()) {
promise.setException(cause);
}
}
complete();
}
private void complete() {
if (0 == numPendings.decrementAndGet() && numFailures.get() == 0) {
promise.setValue(null);
}
}
});
}
}
}, null);
} catch (ZooKeeperClient.ZooKeeperConnectionException e) {
promise.setException(e);
} catch (InterruptedException e) {
promise.setException(e);
}
}
use of com.twitter.util.FutureEventListener in project distributedlog by twitter.
the class FederatedZKLogMetadataStore method findSubNamespaceToCreateLog.
private void findSubNamespaceToCreateLog(final String logName, final Set<URI> uris, final Promise<URI> createPromise) {
final List<URI> uriList = Lists.newArrayListWithExpectedSize(uris.size());
List<Future<Set<String>>> futureList = Lists.newArrayListWithExpectedSize(uris.size());
for (URI uri : uris) {
SubNamespace subNs = subNamespaces.get(uri);
if (null == subNs) {
createPromise.setException(new UnexpectedException("No sub namespace " + uri + " found"));
return;
}
futureList.add(subNs.getLogs());
uriList.add(uri);
}
Future.collect(futureList).addEventListener(new FutureEventListener<List<Set<String>>>() {
@Override
public void onSuccess(List<Set<String>> resultList) {
for (int i = resultList.size() - 1; i >= 0; i--) {
Set<String> logs = resultList.get(i);
if (logs.size() < maxLogsPerSubnamespace) {
URI uri = uriList.get(i);
createLogInNamespace(uri, logName, createPromise);
return;
}
}
// All sub namespaces are full
createSubNamespace().addEventListener(new FutureEventListener<URI>() {
@Override
public void onSuccess(URI uri) {
// the new namespace will be propagated to the namespace cache by the namespace listener
// so we don't need to cache it here. we could go ahead to create the stream under this
// namespace, as we are using sequential znode. we are mostly the first guy who create
// the log under this namespace.
createLogInNamespace(uri, logName, createPromise);
}
@Override
public void onFailure(Throwable cause) {
createPromise.setException(cause);
}
});
}
@Override
public void onFailure(Throwable cause) {
createPromise.setException(cause);
}
});
}
use of com.twitter.util.FutureEventListener in project distributedlog by twitter.
the class SimpleLedgerAllocator method cleanupAndClose.
private void cleanupAndClose(final Promise<Void> closePromise) {
LOG.info("Closing ledger allocator on {}.", allocatePath);
final ZKTransaction txn = new ZKTransaction(zkc);
// try obtain ledger handle
tryObtain(txn, new OpListener<LedgerHandle>() {
@Override
public void onCommit(LedgerHandle r) {
// no-op
complete();
}
@Override
public void onAbort(Throwable t) {
// no-op
complete();
}
private void complete() {
FutureUtils.setValue(closePromise, null);
LOG.info("Closed ledger allocator on {}.", allocatePath);
}
}).addEventListener(new FutureEventListener<LedgerHandle>() {
@Override
public void onSuccess(LedgerHandle lh) {
// try obtain succeed
// if we could obtain the ledger handle, we have the responsibility to close it
deleteLedger(lh.getId());
// wait for deletion to be completed
List<Future<Void>> outstandingDeletions;
synchronized (ledgerDeletions) {
outstandingDeletions = Lists.newArrayList(ledgerDeletions);
}
Future.collect(outstandingDeletions).addEventListener(new FutureEventListener<List<Void>>() {
@Override
public void onSuccess(List<Void> values) {
txn.execute();
}
@Override
public void onFailure(Throwable cause) {
LOG.debug("Fail to obtain the allocated ledger handle when closing the allocator : ", cause);
FutureUtils.setValue(closePromise, null);
}
});
}
@Override
public void onFailure(Throwable cause) {
LOG.debug("Fail to obtain the allocated ledger handle when closing the allocator : ", cause);
FutureUtils.setValue(closePromise, null);
}
});
}
Aggregations