List of usage examples for java.util.concurrent CompletableFuture complete
public boolean complete(T value)
From source file:org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.java
private void offloadLoop(CompletableFuture<PositionImpl> promise, Queue<LedgerInfo> ledgersToOffload, PositionImpl firstUnoffloaded, Optional<Throwable> firstError) { LedgerInfo info = ledgersToOffload.poll(); if (info == null) { if (firstError.isPresent()) { promise.completeExceptionally(firstError.get()); } else {/*from ww w . j a v a2 s.c o m*/ promise.complete(firstUnoffloaded); } } else { long ledgerId = info.getLedgerId(); UUID uuid = UUID.randomUUID(); Map<String, String> extraMetadata = ImmutableMap.of("ManagedLedgerName", name); String driverName = config.getLedgerOffloader().getOffloadDriverName(); Map<String, String> driverMetadata = config.getLedgerOffloader().getOffloadDriverMetadata(); prepareLedgerInfoForOffloaded(ledgerId, uuid, driverName, driverMetadata) .thenCompose((ignore) -> getLedgerHandle(ledgerId)) .thenCompose(readHandle -> config.getLedgerOffloader().offload(readHandle, uuid, extraMetadata)) .thenCompose((ignore) -> { return Retries .run(Backoff.exponentialJittered(TimeUnit.SECONDS.toMillis(1), TimeUnit.SECONDS.toHours(1)).limit(10), FAIL_ON_CONFLICT, () -> completeLedgerInfoForOffloaded(ledgerId, uuid), scheduledExecutor, name) .whenComplete((ignore2, exception) -> { if (exception != null) { cleanupOffloaded(ledgerId, uuid, driverName, driverMetadata, "Metastore failure"); } }); }).whenComplete((ignore, exception) -> { if (exception != null) { log.info("[{}] Exception occurred during offload", name, exception); PositionImpl newFirstUnoffloaded = PositionImpl.get(ledgerId, 0); if (newFirstUnoffloaded.compareTo(firstUnoffloaded) > 0) { newFirstUnoffloaded = firstUnoffloaded; } Optional<Throwable> errorToReport = firstError; synchronized (ManagedLedgerImpl.this) { // if the ledger doesn't exist anymore, ignore the error if (ledgers.containsKey(ledgerId)) { errorToReport = Optional.of(firstError.orElse(exception)); } } offloadLoop(promise, ledgersToOffload, newFirstUnoffloaded, errorToReport); } else { ledgerCache.remove(ledgerId); offloadLoop(promise, ledgersToOffload, firstUnoffloaded, firstError); } }); } }
From source file:org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.java
protected void internalDeletePartitionedTopic(boolean authoritative, boolean force) { validateAdminAccessForTenant(topicName.getTenant()); PartitionedTopicMetadata partitionMetadata = getPartitionedTopicMetadata(topicName, authoritative); int numPartitions = partitionMetadata.partitions; if (numPartitions > 0) { final CompletableFuture<Void> future = new CompletableFuture<>(); final AtomicInteger count = new AtomicInteger(numPartitions); try {/*from w ww . j av a 2 s. c o m*/ for (int i = 0; i < numPartitions; i++) { TopicName topicNamePartition = topicName.getPartition(i); pulsar().getAdminClient().persistentTopics().deleteAsync(topicNamePartition.toString(), force) .whenComplete((r, ex) -> { if (ex != null) { if (ex instanceof NotFoundException) { // if the sub-topic is not found, the client might not have called create // producer or it might have been deleted earlier, so we ignore the 404 error. // For all other exception, we fail the delete partition method even if a single // partition is failed to be deleted if (log.isDebugEnabled()) { log.debug("[{}] Partition not found: {}", clientAppId(), topicNamePartition); } } else { future.completeExceptionally(ex); log.error("[{}] Failed to delete partition {}", clientAppId(), topicNamePartition, ex); return; } } else { log.info("[{}] Deleted partition {}", clientAppId(), topicNamePartition); } if (count.decrementAndGet() == 0) { future.complete(null); } }); } future.get(); } catch (Exception e) { Throwable t = e.getCause(); if (t instanceof PreconditionFailedException) { throw new RestException(Status.PRECONDITION_FAILED, "Topic has active producers/subscriptions"); } else { throw new RestException(t); } } } // Only tries to delete the znode for partitioned topic when all its partitions are successfully deleted String path = path(PARTITIONED_TOPIC_PATH_ZNODE, namespaceName.toString(), domain(), topicName.getEncodedLocalName()); try { globalZk().delete(path, -1); globalZkCache().invalidate(path); // we wait for the data to be synced in all quorums and the observers Thread.sleep(PARTITIONED_TOPIC_WAIT_SYNC_TIME_MS); log.info("[{}] Deleted partitioned topic {}", clientAppId(), topicName); } catch (KeeperException.NoNodeException nne) { throw new RestException(Status.NOT_FOUND, "Partitioned topic does not exist"); } catch (KeeperException.BadVersionException e) { log.warn("[{}] Failed to delete partitioned topic {}: concurrent modification", clientAppId(), topicName); throw new RestException(Status.CONFLICT, "Concurrent modification"); } catch (Exception e) { log.error("[{}] Failed to delete partitioned topic {}", clientAppId(), topicName, e); throw new RestException(e); } }
From source file:org.apache.bookkeeper.mledger.impl.OffloadPrefixTest.java
@Test public void testTrimOccursDuringOffloadLedgerDeletedBeforeOffload() throws Exception { CountDownLatch offloadStarted = new CountDownLatch(1); CompletableFuture<Long> blocker = new CompletableFuture<>(); MockLedgerOffloader offloader = new MockLedgerOffloader() { @Override/*from ww w . ja v a 2 s. c o m*/ public CompletableFuture<Void> offload(ReadHandle ledger, UUID uuid, Map<String, String> extraMetadata) { offloadStarted.countDown(); return blocker.thenCompose((trimmedLedger) -> { if (trimmedLedger == ledger.getId()) { CompletableFuture<Void> future = new CompletableFuture<>(); future.completeExceptionally(new BKException.BKNoSuchLedgerExistsException()); return future; } else { return super.offload(ledger, uuid, extraMetadata); } }); } }; ManagedLedgerConfig config = new ManagedLedgerConfig(); config.setMaxEntriesPerLedger(10); config.setMinimumRolloverTime(0, TimeUnit.SECONDS); config.setRetentionTime(0, TimeUnit.MINUTES); config.setLedgerOffloader(offloader); ManagedLedgerImpl ledger = (ManagedLedgerImpl) factory.open("my_test_ledger", config); ManagedCursor cursor = ledger.openCursor("foobar"); for (int i = 0; i < 21; i++) { String content = "entry-" + i; ledger.addEntry(content.getBytes()); } Assert.assertEquals(ledger.getLedgersInfoAsList().size(), 3); PositionImpl startOfSecondLedger = PositionImpl.get(ledger.getLedgersInfoAsList().get(1).getLedgerId(), 0); PositionImpl startOfThirdLedger = PositionImpl.get(ledger.getLedgersInfoAsList().get(2).getLedgerId(), 0); // trigger an offload which should offload the first two ledgers OffloadCallbackPromise cbPromise = new OffloadCallbackPromise(); ledger.asyncOffloadPrefix(startOfThirdLedger, cbPromise, null); offloadStarted.await(); // trim first ledger long trimmedLedger = ledger.getLedgersInfoAsList().get(0).getLedgerId(); cursor.markDelete(startOfSecondLedger, new HashMap<>()); assertEventuallyTrue(() -> ledger.getLedgersInfoAsList().size() == 2); Assert.assertEquals( ledger.getLedgersInfoAsList().stream().filter(e -> e.getLedgerId() == trimmedLedger).count(), 0); Assert.assertEquals( ledger.getLedgersInfoAsList().stream().filter(e -> e.getOffloadContext().getComplete()).count(), 0); // complete offloading blocker.complete(trimmedLedger); cbPromise.get(); Assert.assertEquals(ledger.getLedgersInfoAsList().size(), 2); Assert.assertEquals( ledger.getLedgersInfoAsList().stream().filter(e -> e.getOffloadContext().getComplete()).count(), 1); Assert.assertTrue(ledger.getLedgersInfoAsList().get(0).getOffloadContext().getComplete()); Assert.assertEquals(offloader.offloadedLedgers().size(), 1); Assert.assertTrue( offloader.offloadedLedgers().contains(ledger.getLedgersInfoAsList().get(0).getLedgerId())); }
From source file:org.apache.pulsar.broker.service.persistent.PersistentTopic.java
private CompletableFuture<? extends Subscription> getNonDurableSubscription(String subscriptionName, MessageId startMessageId) {//from w ww. j av a 2 s . c om CompletableFuture<Subscription> subscriptionFuture = new CompletableFuture<>(); log.info("[{}][{}] Creating non-durable subscription at msg id {}", topic, subscriptionName, startMessageId); // Create a new non-durable cursor only for the first consumer that connects Subscription subscription = subscriptions.computeIfAbsent(subscriptionName, name -> { MessageIdImpl msgId = startMessageId != null ? (MessageIdImpl) startMessageId : (MessageIdImpl) MessageId.latest; long ledgerId = msgId.getLedgerId(); long entryId = msgId.getEntryId(); if (msgId instanceof BatchMessageIdImpl) { // When the start message is relative to a batch, we need to take one step back on the previous message, // because the "batch" might not have been consumed in its entirety. // The client will then be able to discard the first messages in the batch. if (((BatchMessageIdImpl) msgId).getBatchIndex() >= 0) { entryId = msgId.getEntryId() - 1; } } Position startPosition = new PositionImpl(ledgerId, entryId); ManagedCursor cursor = null; try { cursor = ledger.newNonDurableCursor(startPosition); } catch (ManagedLedgerException e) { subscriptionFuture.completeExceptionally(e); } return new PersistentSubscription(this, subscriptionName, cursor); }); if (!subscriptionFuture.isDone()) { subscriptionFuture.complete(subscription); } else { // failed to initialize managed-cursor: clean up created subscription subscriptions.remove(subscriptionName); } return subscriptionFuture; }
From source file:org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.java
private void maybeOffload(CompletableFuture<PositionImpl> finalPromise) { if (!offloadMutex.tryLock()) { scheduledExecutor.schedule(safeRun(() -> maybeOffloadInBackground(finalPromise)), 100, TimeUnit.MILLISECONDS); } else {// w w w. j a va2 s .com CompletableFuture<PositionImpl> unlockingPromise = new CompletableFuture<>(); unlockingPromise.whenComplete((res, ex) -> { offloadMutex.unlock(); if (ex != null) { finalPromise.completeExceptionally(ex); } else { finalPromise.complete(res); } }); long threshold = config.getOffloadAutoTriggerSizeThresholdBytes(); long sizeSummed = 0; long alreadyOffloadedSize = 0; long toOffloadSize = 0; ConcurrentLinkedDeque<LedgerInfo> toOffload = new ConcurrentLinkedDeque(); // go through ledger list from newest to oldest and build a list to offload in oldest to newest order for (Map.Entry<Long, LedgerInfo> e : ledgers.descendingMap().entrySet()) { long size = e.getValue().getSize(); sizeSummed += size; boolean alreadyOffloaded = e.getValue().hasOffloadContext() && e.getValue().getOffloadContext().getComplete(); if (alreadyOffloaded) { alreadyOffloadedSize += size; } else if (sizeSummed > threshold) { toOffloadSize += size; toOffload.addFirst(e.getValue()); } } if (toOffload.size() > 0) { log.info( "[{}] Going to automatically offload ledgers {}" + ", total size = {}, already offloaded = {}, to offload = {}", name, toOffload.stream().map(l -> l.getLedgerId()).collect(Collectors.toList()), sizeSummed, alreadyOffloadedSize, toOffloadSize); } else { // offloadLoop will complete immediately with an empty list to offload log.debug("[{}] Nothing to offload, total size = {}, already offloaded = {}, threshold = {}", name, sizeSummed, alreadyOffloadedSize, threshold); } offloadLoop(unlockingPromise, toOffload, PositionImpl.latest, Optional.empty()); } }
From source file:org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl.java
private void tryTransformLedgerInfo(long ledgerId, LedgerInfoTransformation transformation, CompletableFuture<Void> finalPromise) { synchronized (this) { if (!ledgersListMutex.tryLock()) { // retry in 100 milliseconds scheduledExecutor.schedule(/*from ww w . j a va 2 s.c o m*/ safeRun(() -> tryTransformLedgerInfo(ledgerId, transformation, finalPromise)), 100, TimeUnit.MILLISECONDS); } else { // lock acquired CompletableFuture<Void> unlockingPromise = new CompletableFuture<>(); unlockingPromise.whenComplete((res, ex) -> { ledgersListMutex.unlock(); if (ex != null) { finalPromise.completeExceptionally(ex); } else { finalPromise.complete(res); } }); LedgerInfo oldInfo = ledgers.get(ledgerId); if (oldInfo == null) { unlockingPromise.completeExceptionally(new OffloadConflict( "Ledger " + ledgerId + " no longer exists in ManagedLedger, likely trimmed")); } else { try { LedgerInfo newInfo = transformation.transform(oldInfo); ledgers.put(ledgerId, newInfo); store.asyncUpdateLedgerIds(name, getManagedLedgerInfo(), ledgersStat, new MetaStoreCallback<Void>() { @Override public void operationComplete(Void result, Stat stat) { ledgersStat = stat; unlockingPromise.complete(null); } @Override public void operationFailed(MetaStoreException e) { unlockingPromise.completeExceptionally(e); } }); } catch (ManagedLedgerException mle) { unlockingPromise.completeExceptionally(mle); } } } } }
From source file:org.apache.hadoop.hbase.client.RawAsyncHBaseAdmin.java
private <T> void completeConditionalOnFuture(CompletableFuture<T> dependentFuture, CompletableFuture<T> parentFuture) { addListener(parentFuture, (res, err) -> { if (err != null) { dependentFuture.completeExceptionally(err); } else {/* w ww .ja v a2 s .c o m*/ dependentFuture.complete(res); } }); }
From source file:org.apache.hadoop.hbase.client.RawAsyncHBaseAdmin.java
private CompletableFuture<Boolean> isTableAvailable(TableName tableName, Optional<byte[][]> splitKeys) { if (TableName.isMetaTableName(tableName)) { return connection.registry.getMetaRegionLocation().thenApply(locs -> Stream .of(locs.getRegionLocations()).allMatch(loc -> loc != null && loc.getServerName() != null)); }//from ww w .ja v a 2 s . co m CompletableFuture<Boolean> future = new CompletableFuture<>(); addListener(isTableEnabled(tableName), (enabled, error) -> { if (error != null) { if (error instanceof TableNotFoundException) { future.complete(false); } else { future.completeExceptionally(error); } return; } if (!enabled) { future.complete(false); } else { addListener(AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)), (locations, error1) -> { if (error1 != null) { future.completeExceptionally(error1); return; } List<HRegionLocation> notDeployedRegions = locations.stream() .filter(loc -> loc.getServerName() == null).collect(Collectors.toList()); if (notDeployedRegions.size() > 0) { if (LOG.isDebugEnabled()) { LOG.debug("Table " + tableName + " has " + notDeployedRegions.size() + " regions"); } future.complete(false); return; } Optional<Boolean> available = splitKeys .map(keys -> compareRegionsWithSplitKeys(locations, keys)); future.complete(available.orElse(true)); }); } }); return future; }
From source file:org.apache.hadoop.hbase.client.RawAsyncHBaseAdmin.java
/** * Get the region info for the passed region name. The region name may be a full region name or * encoded region name. If the region does not found, then it'll throw an UnknownRegionException * wrapped by a {@link CompletableFuture} * @param regionNameOrEncodedRegionName//from w w w . jav a2s .c o m * @return region info, wrapped by a {@link CompletableFuture} */ private CompletableFuture<RegionInfo> getRegionInfo(byte[] regionNameOrEncodedRegionName) { if (regionNameOrEncodedRegionName == null) { return failedFuture(new IllegalArgumentException("Passed region name can't be null")); } if (Bytes.equals(regionNameOrEncodedRegionName, RegionInfoBuilder.FIRST_META_REGIONINFO.getRegionName()) || Bytes.equals(regionNameOrEncodedRegionName, RegionInfoBuilder.FIRST_META_REGIONINFO.getEncodedNameAsBytes())) { return CompletableFuture.completedFuture(RegionInfoBuilder.FIRST_META_REGIONINFO); } CompletableFuture<RegionInfo> future = new CompletableFuture<>(); addListener(getRegionLocation(regionNameOrEncodedRegionName), (location, err) -> { if (err != null) { future.completeExceptionally(err); } else { future.complete(location.getRegion()); } }); return future; }
From source file:org.apache.hadoop.hbase.client.RawAsyncHBaseAdmin.java
@Override public CompletableFuture<Boolean> isTableEnabled(TableName tableName) { if (TableName.isMetaTableName(tableName)) { return CompletableFuture.completedFuture(true); }//from w w w. j a v a 2s .co m CompletableFuture<Boolean> future = new CompletableFuture<>(); addListener(AsyncMetaTableAccessor.getTableState(metaTable, tableName), (state, error) -> { if (error != null) { future.completeExceptionally(error); return; } if (state.isPresent()) { future.complete(state.get().inStates(TableState.State.ENABLED)); } else { future.completeExceptionally(new TableNotFoundException(tableName)); } }); return future; }