List of usage examples for java.util.concurrent CompletableFuture completeExceptionally
public boolean completeExceptionally(Throwable ex)
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
private CompletableFuture<Void> checkReplicationAndRetryOnFailure() { CompletableFuture<Void> result = new CompletableFuture<Void>(); checkReplication().thenAccept(res -> { log.info("[{}] Policies updated successfully", topic); result.complete(null);/*w w w. java 2 s .co m*/ }).exceptionally(th -> { log.error("[{}] Policies update failed {}, scheduled retry in {} seconds", topic, th.getMessage(), POLICY_UPDATE_FAILURE_RETRY_TIME_SECONDS, th); brokerService.executor().schedule(this::checkReplicationAndRetryOnFailure, POLICY_UPDATE_FAILURE_RETRY_TIME_SECONDS, TimeUnit.SECONDS); result.completeExceptionally(th); return null; }); return result; }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
private CompletableFuture<Void> checkPersistencePolicies() { TopicName topicName = TopicName.get(topic); CompletableFuture<Void> future = new CompletableFuture<>(); brokerService.getManagedLedgerConfig(topicName).thenAccept(config -> { // update managed-ledger config and managed-cursor.markDeleteRate this.ledger.setConfig(config); future.complete(null);//from w w w. j av a2s. c o m }).exceptionally(ex -> { log.warn("[{}] Failed to update persistence-policies {}", topic, ex.getMessage()); future.completeExceptionally(ex); return null; }); return future; }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
@Override public CompletableFuture<Void> checkReplication() { TopicName name = TopicName.get(topic); if (!name.isGlobal()) { return CompletableFuture.completedFuture(null); }/*from www . ja v a 2s. co m*/ if (log.isDebugEnabled()) { log.debug("[{}] Checking replication status", name); } Policies policies = null; try { policies = brokerService.pulsar().getConfigurationCache().policiesCache() .get(AdminResource.path(POLICIES, name.getNamespace())) .orElseThrow(() -> new KeeperException.NoNodeException()); } catch (Exception e) { CompletableFuture<Void> future = new CompletableFuture<>(); future.completeExceptionally(new ServerMetadataException(e)); return future; } final int newMessageTTLinSeconds = policies.message_ttl_in_seconds; Set<String> configuredClusters; if (policies.replication_clusters != null) { configuredClusters = Sets.newTreeSet(policies.replication_clusters); } else { configuredClusters = Collections.emptySet(); } String localCluster = brokerService.pulsar().getConfiguration().getClusterName(); // if local cluster is removed from global namespace cluster-list : then delete topic forcefully because pulsar // doesn't serve global topic without local repl-cluster configured. if (TopicName.get(topic).isGlobal() && !configuredClusters.contains(localCluster)) { log.info("Deleting topic [{}] because local cluster is not part of global namespace repl list {}", configuredClusters); return deleteForcefully(); } List<CompletableFuture<Void>> futures = Lists.newArrayList(); // Check for missing replicators for (String cluster : configuredClusters) { if (cluster.equals(localCluster)) { continue; } if (!replicators.containsKey(cluster)) { futures.add(startReplicator(cluster)); } } // Check for replicators to be stopped replicators.forEach((cluster, replicator) -> { // Update message TTL ((PersistentReplicator) replicator).updateMessageTTL(newMessageTTLinSeconds); if (!cluster.equals(localCluster)) { if (!configuredClusters.contains(cluster)) { futures.add(removeReplicator(cluster)); } } }); return FutureUtil.waitForAll(futures); }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
CompletableFuture<Void> startReplicator(String remoteCluster) { log.info("[{}] Starting replicator to remote: {}", topic, remoteCluster); final CompletableFuture<Void> future = new CompletableFuture<>(); String name = PersistentReplicator.getReplicatorName(replicatorPrefix, remoteCluster); ledger.asyncOpenCursor(name, new OpenCursorCallback() { @Override/*from w w w .j av a2 s. co m*/ public void openCursorComplete(ManagedCursor cursor, Object ctx) { String localCluster = brokerService.pulsar().getConfiguration().getClusterName(); boolean isReplicatorStarted = addReplicationCluster(remoteCluster, PersistentTopic.this, cursor, localCluster); if (isReplicatorStarted) { future.complete(null); } else { future.completeExceptionally(new NamingException( PersistentTopic.this.getName() + " Failed to start replicator " + remoteCluster)); } } @Override public void openCursorFailed(ManagedLedgerException exception, Object ctx) { future.completeExceptionally(new PersistenceException(exception)); } }, null); return future; }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
CompletableFuture<Void> removeReplicator(String remoteCluster) { log.info("[{}] Removing replicator to {}", topic, remoteCluster); final CompletableFuture<Void> future = new CompletableFuture<>(); String name = PersistentReplicator.getReplicatorName(replicatorPrefix, remoteCluster); replicators.get(remoteCluster).disconnect().thenRun(() -> { ledger.asyncDeleteCursor(name, new DeleteCursorCallback() { @Override/* ww w . ja va 2s .c om*/ public void deleteCursorComplete(Object ctx) { replicators.remove(remoteCluster); future.complete(null); } @Override public void deleteCursorFailed(ManagedLedgerException exception, Object ctx) { log.error("[{}] Failed to delete cursor {} {}", topic, name, exception.getMessage(), exception); future.completeExceptionally(new PersistenceException(exception)); } }, null); }).exceptionally(e -> { log.error("[{}] Failed to close replication producer {} {}", topic, name, e.getMessage(), e); future.completeExceptionally(e); return null; }); return future; }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
@Override public void checkGC(int gcIntervalInSeconds) { if (isActive()) { lastActive = System.nanoTime(); } else if (System.nanoTime() - lastActive < TimeUnit.SECONDS.toNanos(gcIntervalInSeconds)) { // Gc interval did not expire yet return;/*from w w w. j a va 2s. co m*/ } else if (shouldTopicBeRetained()) { // Topic activity is still within the retention period return; } else { CompletableFuture<Void> replCloseFuture = new CompletableFuture<>(); if (TopicName.get(topic).isGlobal()) { // For global namespace, close repl producers first. // Once all repl producers are closed, we can delete the topic, // provided no remote producers connected to the broker. if (log.isDebugEnabled()) { log.debug("[{}] Global topic inactive for {} seconds, closing repl producers.", topic, gcIntervalInSeconds); } closeReplProducersIfNoBacklog().thenRun(() -> { if (hasRemoteProducers()) { if (log.isDebugEnabled()) { log.debug("[{}] Global topic has connected remote producers. Not a candidate for GC", topic); } replCloseFuture.completeExceptionally( new TopicBusyException("Topic has connected remote producers")); } else { log.info("[{}] Global topic inactive for {} seconds, closed repl producers", topic, gcIntervalInSeconds); replCloseFuture.complete(null); } }).exceptionally(e -> { if (log.isDebugEnabled()) { log.debug("[{}] Global topic has replication backlog. Not a candidate for GC", topic); } replCloseFuture.completeExceptionally(e.getCause()); return null; }); } else { replCloseFuture.complete(null); } replCloseFuture.thenCompose(v -> delete(true)) .thenRun(() -> log.info("[{}] Topic deleted successfully due to inactivity", topic)) .exceptionally(e -> { if (e.getCause() instanceof TopicBusyException) { // topic became active again if (log.isDebugEnabled()) { log.debug("[{}] Did not delete busy topic: {}", topic, e.getCause().getMessage()); } } else { log.warn("[{}] Inactive topic deletion failed", topic, e); } return null; }); } }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
public CompletableFuture<MessageId> terminate() { CompletableFuture<MessageId> future = new CompletableFuture<>(); ledger.asyncTerminate(new TerminateCallback() { @Override//from w ww . ja va 2 s. c o m public void terminateComplete(Position lastCommittedPosition, Object ctx) { producers.forEach(Producer::disconnect); subscriptions.forEach((name, sub) -> sub.topicTerminated()); PositionImpl lastPosition = (PositionImpl) lastCommittedPosition; MessageId messageId = new MessageIdImpl(lastPosition.getLedgerId(), lastPosition.getEntryId(), -1); log.info("[{}] Topic terminated at {}", getName(), messageId); future.complete(messageId); } @Override public void terminateFailed(ManagedLedgerException exception, Object ctx) { future.completeExceptionally(exception); } }, null); return future; }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
public synchronized void triggerOffload(MessageIdImpl messageId) throws AlreadyRunningException { if (currentOffload.isDone()) { CompletableFuture<MessageIdImpl> promise = currentOffload = new CompletableFuture<>(); getManagedLedger().asyncOffloadPrefix(PositionImpl.get(messageId.getLedgerId(), messageId.getEntryId()), new OffloadCallback() { @Override//from w w w. jav a2s . co m public void offloadComplete(Position pos, Object ctx) { PositionImpl impl = (PositionImpl) pos; promise.complete(new MessageIdImpl(impl.getLedgerId(), impl.getEntryId(), -1)); } @Override public void offloadFailed(ManagedLedgerException exception, Object ctx) { promise.completeExceptionally(exception); } }, null); } else { throw new AlreadyRunningException("Offload already in progress"); } }
From source file:org.apache.pulsar.broker.web.PulsarWebResource.java
protected static CompletableFuture<ClusterData> getClusterDataIfDifferentCluster(PulsarService pulsar, String cluster, String clientAppId) { CompletableFuture<ClusterData> clusterDataFuture = new CompletableFuture<>(); if (!isValidCluster(pulsar, cluster)) { try {/*from ww w .ja v a 2 s. co m*/ // this code should only happen with a v1 namespace format prop/cluster/namespaces if (!pulsar.getConfiguration().getClusterName().equals(cluster)) { // redirect to the cluster requested pulsar.getConfigurationCache().clustersCache().getAsync(path("clusters", cluster)) .thenAccept(clusterDataResult -> { if (clusterDataResult.isPresent()) { clusterDataFuture.complete(clusterDataResult.get()); } else { log.warn("[{}] Cluster does not exist: requested={}", clientAppId, cluster); clusterDataFuture.completeExceptionally(new RestException(Status.NOT_FOUND, "Cluster does not exist: cluster=" + cluster)); } }).exceptionally(ex -> { clusterDataFuture.completeExceptionally(ex); return null; }); } else { clusterDataFuture.complete(null); } } catch (Exception e) { clusterDataFuture.completeExceptionally(e); } } else { clusterDataFuture.complete(null); } return clusterDataFuture; }
From source file:org.apache.pulsar.broker.web.PulsarWebResource.java
public static CompletableFuture<ClusterData> checkLocalOrGetPeerReplicationCluster(PulsarService pulsarService, NamespaceName namespace) {// w ww .j av a 2 s.co m if (!namespace.isGlobal()) { return CompletableFuture.completedFuture(null); } final CompletableFuture<ClusterData> validationFuture = new CompletableFuture<>(); final String localCluster = pulsarService.getConfiguration().getClusterName(); final String path = AdminResource.path(POLICIES, namespace.toString()); pulsarService.getConfigurationCache().policiesCache().getAsync(path).thenAccept(policiesResult -> { if (policiesResult.isPresent()) { Policies policies = policiesResult.get(); if (policies.replication_clusters.isEmpty()) { String msg = String.format( "Namespace does not have any clusters configured : local_cluster=%s ns=%s", localCluster, namespace.toString()); log.warn(msg); validationFuture.completeExceptionally(new RestException(Status.PRECONDITION_FAILED, msg)); } else if (!policies.replication_clusters.contains(localCluster)) { ClusterData ownerPeerCluster = getOwnerFromPeerClusterList(pulsarService, policies.replication_clusters); if (ownerPeerCluster != null) { // found a peer that own this namespace validationFuture.complete(ownerPeerCluster); return; } String msg = String.format( "Namespace missing local cluster name in clusters list: local_cluster=%s ns=%s clusters=%s", localCluster, namespace.toString(), policies.replication_clusters); log.warn(msg); validationFuture.completeExceptionally(new RestException(Status.PRECONDITION_FAILED, msg)); } else { validationFuture.complete(null); } } else { String msg = String.format("Policies not found for %s namespace", namespace.toString()); log.error(msg); validationFuture.completeExceptionally(new RestException(Status.NOT_FOUND, msg)); } }).exceptionally(ex -> { String msg = String.format( "Failed to validate global cluster configuration : cluster=%s ns=%s emsg=%s", localCluster, namespace, ex.getMessage()); log.error(msg); validationFuture.completeExceptionally(new RestException(ex)); return null; }); return validationFuture; }