FutureUtil.waitForAll(futures).thenRun(() -> {
@Override public CompletableFuture<Void> unsubscribeAsync() { if (getState() == State.Closing || getState() == State.Closed) { return FutureUtil.failedFuture( new PulsarClientException.AlreadyClosedException("Topics Consumer was already closed")); } setState(State.Closing); CompletableFuture<Void> unsubscribeFuture = new CompletableFuture<>(); List<CompletableFuture<Void>> futureList = consumers.values().stream() .map(c -> c.unsubscribeAsync()).collect(Collectors.toList()); FutureUtil.waitForAll(futureList) .whenComplete((r, ex) -> { if (ex == null) { setState(State.Closed); unAckedMessageTracker.close(); unsubscribeFuture.complete(null); log.info("[{}] [{}] [{}] Unsubscribed Topics Consumer", topic, subscription, consumerName); } else { setState(State.Failed); unsubscribeFuture.completeExceptionally(ex); log.error("[{}] [{}] [{}] Could not unsubscribe Topics Consumer", topic, subscription, consumerName, ex.getCause()); } }); return unsubscribeFuture; }
@Override public CompletableFuture<Void> closeAsync() { if (getState() == State.Closing || getState() == State.Closed) { unAckedMessageTracker.close(); return CompletableFuture.completedFuture(null); } setState(State.Closing); CompletableFuture<Void> closeFuture = new CompletableFuture<>(); List<CompletableFuture<Void>> futureList = consumers.values().stream() .map(c -> c.closeAsync()).collect(Collectors.toList()); FutureUtil.waitForAll(futureList) .whenComplete((r, ex) -> { if (ex == null) { setState(State.Closed); unAckedMessageTracker.close(); closeFuture.complete(null); log.info("[{}] [{}] Closed Topics Consumer", topic, subscription); client.cleanupConsumer(this); // fail all pending-receive futures to notify application failPendingReceive(); } else { setState(State.Failed); closeFuture.completeExceptionally(ex); log.error("[{}] [{}] Could not close Topics Consumer", topic, subscription, ex.getCause()); } }); return closeFuture; }
.map(ConsumerImpl::unsubscribeAsync).collect(Collectors.toList()); FutureUtil.waitForAll(futureList) .whenComplete((r, ex) -> { if (ex == null) {
@Override public void run(Timeout timeout) throws Exception { if (timeout.isCancelled()) { return; } CompletableFuture<Void> recheckFuture = new CompletableFuture<>(); List<CompletableFuture<Void>> futures = Lists.newArrayListWithExpectedSize(2); client.getLookup().getTopicsUnderNamespace(namespaceName, subscriptionMode).thenAccept(topics -> { if (log.isDebugEnabled()) { log.debug("Get topics under namespace {}, topics.size: {}", namespaceName.toString(), topics.size()); topics.forEach(topicName -> log.debug("Get topics under namespace {}, topic: {}", namespaceName.toString(), topicName)); } List<String> newTopics = PulsarClientImpl.topicsPatternFilter(topics, topicsPattern); List<String> oldTopics = PatternMultiTopicsConsumerImpl.this.getTopics(); futures.add(topicsChangeListener.onTopicsAdded(topicsListsMinus(newTopics, oldTopics))); futures.add(topicsChangeListener.onTopicsRemoved(topicsListsMinus(oldTopics, newTopics))); FutureUtil.waitForAll(futures) .thenAccept(finalFuture -> recheckFuture.complete(null)) .exceptionally(ex -> { log.warn("[{}] Failed to recheck topics change: {}", topic, ex.getMessage()); recheckFuture.completeExceptionally(ex); return null; }); }); // schedule the next re-check task client.timer().newTimeout(PatternMultiTopicsConsumerImpl.this, Math.min(1, conf.getPatternAutoDiscoveryPeriod()), TimeUnit.MINUTES); }
FutureUtil.waitForAll(futureList) .thenAccept(finalFuture -> { try {
FutureUtil.waitForAll(futures) .thenAccept(finalFuture -> { try {
/** * Send a request to multiple hosts and wait for all responses */ private void sendPost(List<String> hosts, String path, byte[] body) { FutureUtil.waitForAll(hosts.stream().map(w -> sendPost(w, path, body)).collect(toList())).join(); }
private <T> List<T> get(List<String> hosts, String path, Class<T> clazz) { List<CompletableFuture<T>> futures = hosts.stream().map(w -> get(w, path, clazz)).collect(toList()); CompletableFuture<List<T>> resultFuture = new CompletableFuture<>(); FutureUtil.waitForAll(futures).thenRun(() -> { resultFuture.complete(futures.stream().map(CompletableFuture::join).collect(toList())); }).exceptionally(ex -> { resultFuture.completeExceptionally(ex); return null; }); return resultFuture.join(); }
public CompletableFuture<Void> stopReplProducers() { List<CompletableFuture<Void>> closeFutures = Lists.newArrayList(); replicators.forEach((region, replicator) -> closeFutures.add(replicator.disconnect())); return FutureUtil.waitForAll(closeFutures); }
private synchronized CompletableFuture<Void> closeReplProducersIfNoBacklog() { List<CompletableFuture<Void>> closeFutures = Lists.newArrayList(); replicators.forEach((region, replicator) -> closeFutures.add(replicator.disconnect(true))); return FutureUtil.waitForAll(closeFutures); }
public CompletableFuture<Void> stopReplProducers() { List<CompletableFuture<Void>> closeFutures = Lists.newArrayList(); replicators.forEach((region, replicator) -> closeFutures.add(replicator.disconnect())); return FutureUtil.waitForAll(closeFutures); }
/** * Unload all the topic served by the broker service under the given service unit * * @param serviceUnit * @return */ public CompletableFuture<Integer> unloadServiceUnit(NamespaceBundle serviceUnit) { CompletableFuture<Integer> result = new CompletableFuture<Integer>(); List<CompletableFuture<Void>> closeFutures = Lists.newArrayList(); topics.forEach((name, topicFuture) -> { TopicName topicName = TopicName.get(name); if (serviceUnit.includes(topicName)) { // Topic needs to be unloaded log.info("[{}] Unloading topic", topicName); closeFutures.add(topicFuture .thenCompose(t -> t.isPresent() ? t.get().close() : CompletableFuture.completedFuture(null))); } }); CompletableFuture<Void> aggregator = FutureUtil.waitForAll(closeFutures); aggregator.thenAccept(res -> result.complete(closeFutures.size())).exceptionally(ex -> { result.completeExceptionally(ex); return null; }); return result; }
@Override public void createProducers(List<String> topics) { List<List<String>> topicsPerProducer = ListPartition.partitionList(topics, producerWorkers.size()); Map<String, List<String>> topicsPerProducerMap = Maps.newHashMap(); int i = 0; for (List<String> assignedTopics : topicsPerProducer) { topicsPerProducerMap.put(producerWorkers.get(i++), assignedTopics); } // Number of actually used workers might be less than available workers numberOfUsedProducerWorkers = i; List<CompletableFuture<Void>> futures = topicsPerProducerMap.keySet().stream().map(producer -> { try { return sendPost(producer, "/create-producers", writer.writeValueAsBytes(topicsPerProducerMap.get(producer))); } catch (Exception e) { CompletableFuture<Void> future = new CompletableFuture<>(); future.completeExceptionally(e); return future; } }).collect(toList()); FutureUtil.waitForAll(futures).join(); }
@Override public void createConsumers(ConsumerAssignment overallConsumerAssignment) { List<List<TopicSubscription>> subscriptionsPerConsumer = ListPartition.partitionList( overallConsumerAssignment.topicsSubscriptions, consumerWorkers.size()); Map<String, ConsumerAssignment> topicsPerWorkerMap = Maps.newHashMap(); int i = 0; for (List<TopicSubscription> tsl : subscriptionsPerConsumer) { ConsumerAssignment individualAssignement = new ConsumerAssignment(); individualAssignement.topicsSubscriptions = tsl; topicsPerWorkerMap.put(consumerWorkers.get(i++), individualAssignement); } List<CompletableFuture<Void>> futures = topicsPerWorkerMap.keySet().stream().map(consumer -> { try { return sendPost(consumer, "/create-consumers", writer.writeValueAsBytes(topicsPerWorkerMap.get(consumer))); } catch (Exception e) { CompletableFuture<Void> future = new CompletableFuture<>(); future.completeExceptionally(e); return future; } }).collect(toList()); FutureUtil.waitForAll(futures).join(); }
/** * Method to remove ownership of all owned bundles * * @param bundles * <code>NamespaceBundles</code> to remove from ownership cache */ public CompletableFuture<Void> removeOwnership(NamespaceBundles bundles) { List<CompletableFuture<Void>> allFutures = Lists.newArrayList(); for (NamespaceBundle bundle : bundles.getBundles()) { if (getOwnedBundle(bundle) == null) { // continue continue; } allFutures.add(this.removeOwnership(bundle)); } return FutureUtil.waitForAll(allFutures); }
/** * Clears backlog for all cursors in the topic * * @return */ public CompletableFuture<Void> clearBacklog() { log.info("[{}] Clearing backlog on all cursors in the topic.", topic); List<CompletableFuture<Void>> futures = Lists.newArrayList(); List<String> cursors = getSubscriptions().keys(); cursors.addAll(getReplicators().keys()); for (String cursor : cursors) { futures.add(clearBacklog(cursor)); } return FutureUtil.waitForAll(futures); }
@Override public CompletableFuture<Void> closeAsync() { if (getState() == State.Closing || getState() == State.Closed) { unAckedMessageTracker.close(); return CompletableFuture.completedFuture(null); } setState(State.Closing); CompletableFuture<Void> closeFuture = new CompletableFuture<>(); List<CompletableFuture<Void>> futureList = consumers.values().stream() .map(c -> c.closeAsync()).collect(Collectors.toList()); FutureUtil.waitForAll(futureList) .whenComplete((r, ex) -> { if (ex == null) { setState(State.Closed); unAckedMessageTracker.close(); closeFuture.complete(null); log.info("[{}] [{}] Closed Topics Consumer", topic, subscription); client.cleanupConsumer(this); // fail all pending-receive futures to notify application failPendingReceive(); } else { setState(State.Failed); closeFuture.completeExceptionally(ex); log.error("[{}] [{}] Could not close Topics Consumer", topic, subscription, ex.getCause()); } }); return closeFuture; }
/** * Disconnect producers on given topic * * @param persistentTopic * The topic on which all producers should be disconnected */ private void disconnectProducers(PersistentTopic persistentTopic) { List<CompletableFuture<Void>> futures = Lists.newArrayList(); ConcurrentOpenHashSet<Producer> producers = persistentTopic.getProducers(); producers.forEach(producer -> { log.info("Producer [{}] has exceeded backlog quota on topic [{}]. Disconnecting producer", producer.getProducerName(), persistentTopic.getName()); futures.add(producer.disconnect()); }); FutureUtil.waitForAll(futures).thenRun(() -> { log.info("All producers on topic [{}] are disconnected", persistentTopic.getName()); }).exceptionally(exception -> { log.error("Error in disconnecting producers on topic [{}] [{}]", persistentTopic.getName(), exception); return null; }); } }
private void clearBacklog(NamespaceName nsName, String bundleRange, String subscription) { try { List<Topic> topicList = pulsar().getBrokerService().getAllTopicsFromNamespaceBundle(nsName.toString(), nsName.toString() + "/" + bundleRange); List<CompletableFuture<Void>> futures = Lists.newArrayList(); if (subscription != null) { if (subscription.startsWith(pulsar().getConfiguration().getReplicatorPrefix())) { subscription = PersistentReplicator.getRemoteCluster(subscription); } for (Topic topic : topicList) { if (topic instanceof PersistentTopic) { futures.add(((PersistentTopic) topic).clearBacklog(subscription)); } } } else { for (Topic topic : topicList) { if (topic instanceof PersistentTopic) { futures.add(((PersistentTopic) topic).clearBacklog()); } } } FutureUtil.waitForAll(futures).get(); } catch (Exception e) { log.error("[{}] Failed to clear backlog for namespace {}/{}, subscription: {}", clientAppId(), nsName.toString(), bundleRange, subscription, e); throw new RestException(e); } }