Example usage for java.util.concurrent CompletableFuture complete

List of usage examples for java.util.concurrent CompletableFuture complete

Introduction

In this page you can find the example usage for java.util.concurrent CompletableFuture complete.

Prototype

public boolean complete(T value) 

Source Link

Document

If not already completed, sets the value returned by #get() and related methods to the given value.

Usage

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;
}