com.spotify.futures.CompletableFutures Java Examples

The following examples show how to use com.spotify.futures.CompletableFutures. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BackfillResource.java    From styx with Apache License 2.0 6 votes vote down vote up
private CompletionStage<Response<ByteString>> haltActiveBackfillInstances(Backfill backfill, Client client) {
  return CompletableFutures.allAsList(
      retrieveBackfillStatuses(backfill).stream()
          .filter(BackfillResource::isActiveState)
          .map(RunStateData::workflowInstance)
          .map(workflowInstance -> haltActiveBackfillInstance(workflowInstance, client))
          .collect(toList()))
      .handle((result, throwable) -> {
        if (throwable != null || result.contains(Boolean.FALSE)) {
          return Response.forStatus(
              Status.INTERNAL_SERVER_ERROR
                  .withReasonPhrase(
                      "some active instances cannot be halted, however no new ones will be triggered"));
        } else {
          return Response.ok();
        }
      });
}
 
Example #2
Source File: SimpleEventProcessor.java    From conductor with Apache License 2.0 6 votes vote down vote up
/**
 * @param eventHandler the {@link EventHandler} for which the actions are to be executed
 * @param msg          the {@link Message} that triggered the event
 * @return a {@link CompletableFuture} holding a list of {@link EventExecution}s for the {@link Action}s executed in the event handler
 */
private CompletableFuture<List<EventExecution>> executeActionsForEventHandler(EventHandler eventHandler, Message msg) {
    List<CompletableFuture<EventExecution>> futuresList = new ArrayList<>();
    int i = 0;
    for (Action action : eventHandler.getActions()) {
        String id = msg.getId() + "_" + i++;
        EventExecution eventExecution = new EventExecution(id, msg.getId());
        eventExecution.setCreated(System.currentTimeMillis());
        eventExecution.setEvent(eventHandler.getEvent());
        eventExecution.setName(eventHandler.getName());
        eventExecution.setAction(action.getAction());
        eventExecution.setStatus(Status.IN_PROGRESS);
        if (executionService.addEventExecution(eventExecution)) {
            futuresList.add(CompletableFuture.supplyAsync(() -> execute(eventExecution, action, getPayloadObject(msg.getPayload())), executorService));
        } else {
            logger.warn("Duplicate delivery/execution of message: {}", msg.getId());
        }
    }
    return CompletableFutures.allAsList(futuresList);
}
 
Example #3
Source File: AuthenticatePlainCommand.java    From NioImapClient with Apache License 2.0 5 votes vote down vote up
public CompletableFuture<TaggedResponse> continueAfterResponse(ImapResponse imapResponse, Throwable throwable) {
  if (throwable != null) {
    return CompletableFutures.exceptionallyCompletedFuture(throwable);
  }

  String toEncode = NUL + user + NUL + password;
  String base64EncodedAuthRequest = BaseEncoding.base64().encode(toEncode.getBytes(StandardCharsets.UTF_8));
  return imapClient.send(new SimpleStringCommand(base64EncodedAuthRequest));
}
 
Example #4
Source File: DefaultStreamMessageDuplicator.java    From armeria with Apache License 2.0 5 votes vote down vote up
private void doCleanup(Throwable cause) {
    final List<CompletableFuture<Void>> completionFutures =
            new ArrayList<>(downstreamSubscriptions.size());
    downstreamSubscriptions.forEach(s -> {
        s.abort(cause);
        final CompletableFuture<Void> future = s.whenComplete();
        completionFutures.add(future);
    });
    downstreamSubscriptions.clear();
    CompletableFutures.successfulAsList(completionFutures, unused -> null)
                      .handle((unused1, unused2) -> {
                          signals.clear();
                          return null;
                      });
}
 
Example #5
Source File: AuthorizerUtil.java    From armeria with Apache License 2.0 5 votes vote down vote up
/**
 * Determines if the specified {@code data} is authorized for this service. If the result resolves
 * to {@code true}, the request is authorized, or {@code false} otherwise. If the future resolves
 * exceptionally, the request will not be authorized.
 */
static <T> CompletionStage<Boolean> authorize(Authorizer<T> authorizer, ServiceRequestContext ctx, T data) {
    try {
        final CompletionStage<Boolean> f = authorizer.authorize(ctx, data);
        if (f == null) {
            throw new NullPointerException("An " + Authorizer.class.getSimpleName() +
                                           " returned null: " + authorizer);
        }
        return f;
    } catch (Throwable cause) {
        return CompletableFutures.exceptionallyCompletedFuture(cause);
    }
}
 
Example #6
Source File: PersistentStateManager.java    From styx with Apache License 2.0 5 votes vote down vote up
@Override
public void tick() {
  var shuffledInstances = new ArrayList<>(Try.of(storage::listActiveInstances).get());
  Collections.shuffle(shuffledInstances);
  var futures = shuffledInstances.stream()
      .map(instance -> CompletableFuture.runAsync(() -> tickInstance(instance), executor))
      .collect(toList());
  CompletableFutures.allAsList(futures).join();
}
 
Example #7
Source File: CentralDogmaRule.java    From centraldogma with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)},
 * and starts the server asynchronously.
 */
public final CompletableFuture<Void> startAsync() {
    // Create the root folder first if it doesn't exist.
    try {
        getRoot();
    } catch (IllegalStateException unused) {
        try {
            create();
        } catch (IOException e) {
            return CompletableFutures.exceptionallyCompletedFuture(e);
        }
    }

    return delegate.startAsync(getRoot());
}
 
Example #8
Source File: CentralDogmaExtension.java    From centraldogma with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)},
 * and starts the server asynchronously.
 */
public final CompletableFuture<Void> startAsync() {
    // Create the root folder first if it doesn't exist.
    if (!dataDir.exists()) {
        try {
            dataDir.create();
        } catch (IOException e) {
            return CompletableFutures.exceptionallyCompletedFuture(e);
        }
    }

    return delegate.startAsync(dataDir.getRoot().toFile());
}
 
Example #9
Source File: Repository.java    From centraldogma with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the {@link CompletableFuture} whose value is the absolute {@link Revision} of the
 * specified {@link Revision}.
 *
 * @deprecated Use {@link #normalizeNow(Revision)}.
 */
@Deprecated
default CompletableFuture<Revision> normalize(Revision revision) {
    try {
        return CompletableFuture.completedFuture(normalizeNow(revision));
    } catch (Exception e) {
        return CompletableFutures.exceptionallyCompletedFuture(e);
    }
}
 
Example #10
Source File: MetadataService.java    From centraldogma with Apache License 2.0 5 votes vote down vote up
private CompletableFuture<HolderWithRevision<ProjectMetadata>> fetchMetadata(String projectName) {
    return fetchMetadata0(projectName).thenCompose(holder -> {
        final Set<String> repos = projectManager.get(projectName).repos().list().keySet();
        final Set<String> reposWithMetadata = holder.object().repos().keySet();

        // Make sure all repositories have metadata. If not, create missing metadata.
        // A repository can have missing metadata when a dev forgot to call `addRepo()`
        // after creating a new repository.
        final ImmutableList.Builder<CompletableFuture<Revision>> builder = ImmutableList.builder();
        for (String repo : repos) {
            if (reposWithMetadata.contains(repo) ||
                repo.equals(Project.REPO_DOGMA)) {
                continue;
            }

            logger.warn("Adding missing repository metadata: {}/{}", projectName, repo);
            builder.add(addRepo(Author.SYSTEM, projectName, repo));
        }

        final ImmutableList<CompletableFuture<Revision>> futures = builder.build();
        if (futures.isEmpty()) {
            // All repositories have metadata.
            return CompletableFuture.completedFuture(holder);
        }

        // Some repository did not have metadata and thus will add the missing ones.
        return CompletableFutures.allAsList(futures).thenCompose(unused -> {
            logger.info("Fetching {}/{}{} again",
                        projectName, Project.REPO_DOGMA, METADATA_JSON);
            return fetchMetadata0(projectName);
        });
    });
}
 
Example #11
Source File: LegacyCentralDogma.java    From centraldogma with Apache License 2.0 5 votes vote down vote up
private static <T> CompletableFuture<T> run(ThriftCall<T> call) {
    final ThriftFuture<T> future = new ThriftFuture<>();
    try {
        call.apply(future);
        return future.exceptionally(cause -> Exceptions.throwUnsafely(convertCause(cause)));
    } catch (Exception e) {
        return CompletableFutures.exceptionallyCompletedFuture(convertCause(e));
    }
}
 
Example #12
Source File: TensorFlowPredictFn.java    From zoltar with Apache License 2.0 5 votes vote down vote up
/**
 * TensorFlow Example prediction function.
 *
 * @deprecated Use {@link #example(Function, String...)}
 * @param outTensorExtractor Function to extract the output value from JTensor's
 * @param fetchOps operations to fetch.
 */
@Deprecated
static <InputT, ValueT> TensorFlowPredictFn<InputT, List<Example>, ValueT> exampleBatch(
    final Function<Map<String, JTensor>, ValueT> outTensorExtractor, final String... fetchOps) {
  final BiFunction<TensorFlowModel, List<Example>, ValueT> predictFn =
      (model, examples) -> {
        final byte[][] bytes = examples.stream().map(Example::toByteArray).toArray(byte[][]::new);

        try (final Tensor<String> t = Tensors.create(bytes)) {
          final Session.Runner runner =
              model.instance().session().runner().feed("input_example_tensor", t);
          final Map<String, JTensor> result = TensorFlowExtras.runAndExtract(runner, fetchOps);

          return outTensorExtractor.apply(result);
        }
      };

  return (model, vectors) -> {
    final List<CompletableFuture<Prediction<InputT, ValueT>>> predictions =
        vectors
            .stream()
            .map(
                vector ->
                    CompletableFuture.supplyAsync(() -> predictFn.apply(model, vector.value()))
                        .thenApply(v -> Prediction.create(vector.input(), v)))
            .collect(Collectors.toList());

    return CompletableFutures.allAsList(predictions);
  };
}
 
Example #13
Source File: Repository.java    From centraldogma with Apache License 2.0 4 votes vote down vote up
/**
 * Merges the JSON files sequentially as specified in the {@link MergeQuery}.
 */
default <T> CompletableFuture<MergedEntry<T>> mergeFiles(Revision revision, MergeQuery<T> query) {
    requireNonNull(revision, "revision");
    requireNonNull(query, "query");

    final List<MergeSource> mergeSources = query.mergeSources();
    // Only JSON files can currently be merged.
    mergeSources.forEach(path -> validateJsonFilePath(path.path(), "path"));

    final Revision normalizedRevision;
    try {
        normalizedRevision = normalizeNow(revision);
    } catch (Exception e) {
        return CompletableFutures.exceptionallyCompletedFuture(e);
    }
    final List<CompletableFuture<Entry<?>>> entryFutures = new ArrayList<>(mergeSources.size());
    mergeSources.forEach(path -> {
        if (!path.isOptional()) {
            entryFutures.add(get(normalizedRevision, path.path()));
        } else {
            entryFutures.add(getOrNull(normalizedRevision, path.path()));
        }
    });

    final CompletableFuture<MergedEntry<?>> mergedEntryFuture = mergeEntries(entryFutures, revision,
                                                                             query);
    final CompletableFuture<MergedEntry<T>> future = new CompletableFuture<>();
    mergedEntryFuture.handle((mergedEntry, cause) -> {
        if (cause != null) {
            if (!(cause instanceof CentralDogmaException)) {
                cause = new QueryExecutionException(cause);
            }
            future.completeExceptionally(cause);
            return null;
        }
        future.complete(unsafeCast(mergedEntry));
        return null;
    });

    return future;
}
 
Example #14
Source File: MlEnginePredictorExample.java    From zoltar with Apache License 2.0 4 votes vote down vote up
/** Runs a simple Iris prediction against the running Iris ml-engine instance. */
public static MlEnginePredictorExample create(
    final String projectId, final String modelId, final String versionId) throws Exception {
  // #MlEngineLoader
  final MlEngineLoader mlEngineLoader = Models.mlEngine(projectId, modelId, versionId);
  // #MlEngineLoader

  final FeatureSpec<Iris> irisFeatureSpec = IrisFeaturesSpec.irisFeaturesSpec();
  final URI settingsUri = MlEnginePredictorExample.class.getResource("/settings.json").toURI();
  final String settings = new String(Files.readAllBytes(Paths.get(settingsUri)));
  final ExtractFn<Iris, Example> extractFn = FeatranExtractFns.example(irisFeatureSpec, settings);

  final MlEnginePredictFn<Iris, Example, Integer> predictFn =
      (model, vectors) -> {
        final List<CompletableFuture<Prediction<Iris, Integer>>> predictions =
            vectors
                .stream()
                .map(
                    vector ->
                        CompletableFuture.supplyAsync(
                                () -> {
                                  try {
                                    final List<Example> input =
                                        Collections.singletonList(vector.value());
                                    final MlEnginePrediction result =
                                        model
                                            .predictExamples(input)
                                            .values(MlEnginePrediction.class)
                                            .get(0);

                                    final int max =
                                        IntStream.range(0, result.scores().size())
                                            .reduce(
                                                (i, j) -> {
                                                  final BigDecimal ci = result.scores().get(i);
                                                  final BigDecimal cj = result.scores().get(j);
                                                  return ci.compareTo(cj) > 0 ? i : j;
                                                })
                                            .getAsInt();

                                    return result.classes().get(max);
                                  } catch (IOException
                                      | MlEnginePredictException
                                      | ExecutionException e) {
                                    throw new RuntimeException(e);
                                  }
                                })
                            .thenApply(v -> Prediction.create(vector.input(), v)))
                .collect(Collectors.toList());
        return CompletableFutures.allAsList(predictions);
      };

  final Predictor<Iris, Integer> predictor =
      Predictors.newBuilder(mlEngineLoader, extractFn, predictFn).predictor();

  return new MlEnginePredictorExample(predictor);
}
 
Example #15
Source File: ImapClient.java    From NioImapClient with Apache License 2.0 4 votes vote down vote up
public synchronized <T extends TaggedResponse, A extends ContinuableCommand<T>> CompletableFuture<T> send(A imapCommand) {
  return CompletableFutures.handleCompose(sendRaw(imapCommand), imapCommand::continueAfterResponse).toCompletableFuture();
}
 
Example #16
Source File: MainService.java    From armeria with Apache License 2.0 4 votes vote down vote up
@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) {
    final Executor ctxExecutor = ctx.contextAwareExecutor();

    final CompletableFuture<AggregatedHttpRequest> aggregated = req.aggregate();

    // This logic mimics using a blocking method, which would usually be something like a MySQL
    // database query using JDBC.
    final CompletableFuture<List<Long>> fetchFromFakeDb = CompletableFuture.supplyAsync(
            () -> {
                // The context is mounted in a thread-local, meaning it is available to all logic such
                // as tracing.
                checkState(ServiceRequestContext.current() == ctx);
                checkState(!ctx.eventLoop().inEventLoop());

                Uninterruptibles.sleepUninterruptibly(Duration.ofMillis(50));
                return ImmutableList.of(23L, -23L);
            },
            // Always run blocking logic on the blocking task executor. By using
            // ServiceRequestContext.blockingTaskExecutor, you also ensure the context is mounted inside the
            // logic (e.g., your DB call will be traced!).
            ctx.blockingTaskExecutor());

    final CompletableFuture<List<CompletableFuture<AggregatedHttpResponse>>> fetchFromBackend =
            CompletableFuture.allOf(
                    aggregated, fetchFromFakeDb).thenApplyAsync(
                    unused -> {
                        // The context is mounted in a thread-local, meaning it is available to all logic
                        // such as tracing.
                        checkState(ServiceRequestContext.current() == ctx);
                        checkState(ctx.eventLoop().inEventLoop());

                        final AggregatedHttpRequest request = aggregated.join();

                        final Stream.Builder<Long> nums = Stream.builder();
                        for (String token : Iterables.concat(
                                NUM_SPLITTER.split(request.path().substring(1)),
                                NUM_SPLITTER.split(request.contentUtf8()))) {
                            nums.add(Long.parseLong(token));
                        }
                        fetchFromFakeDb.join().forEach(nums::add);

                        return nums.build()
                                   .map(num -> backendClient.get("/square/" + num).aggregate())
                                   .collect(toImmutableList());
                    },
                    // Unless you know what you're doing, always use then*Async type methods with the
                    // context executor to have the context mounted and stay on a single thread to reduce
                    // concurrency issues.
                    ctxExecutor);

    final CompletableFuture<HttpResponse> response =
            // When using CompletableFuture, boiler-plate invocations to wrap / unwrap futures are sometimes
            // required. Such boilerplate has no chance of using Armeria's context and it is ok to not
            // use ctxExecutor for them. But if in doubt, it doesn't hurt too much to use it everywhere.
            fetchFromBackend.thenApply(CompletableFutures::allAsList)
                            .thenCompose(u -> u)
                            .thenApplyAsync(
                                    (backendResponse) -> {
                                        // The context is mounted in a thread-local, meaning it is
                                        // available to all logic such as tracing.
                                        checkState(ServiceRequestContext.current() == ctx);
                                        checkState(ctx.eventLoop().inEventLoop());
                                        return HttpResponse.of(
                                                backendResponse.stream()
                                                               .map(AggregatedHttpResponse::contentUtf8)
                                                               .collect(Collectors.joining("\n")));
                                    },
                                    // Unless you know what you're doing, always use then*Async type
                                    // methods with the context executor to have the context mounted and
                                    // stay on a single thread to reduce concurrency issues.
                                    ctxExecutor);

    return HttpResponse.from(response);
}
 
Example #17
Source File: Server.java    From armeria with Apache License 2.0 4 votes vote down vote up
private void finishDoStop(CompletableFuture<Void> future) {
    serverChannels.clear();

    if (config.shutdownBlockingTaskExecutorOnStop()) {
        final ScheduledExecutorService executor;
        final ScheduledExecutorService blockingTaskExecutor = config.blockingTaskExecutor();
        if (blockingTaskExecutor instanceof UnstoppableScheduledExecutorService) {
            executor =
                    ((UnstoppableScheduledExecutorService) blockingTaskExecutor).getExecutorService();
        } else {
            executor = blockingTaskExecutor;
        }

        try {
            executor.shutdown();
            while (!executor.isTerminated()) {
                try {
                    executor.awaitTermination(1, TimeUnit.DAYS);
                } catch (InterruptedException ignore) {
                    // Do nothing.
                }
            }
        } catch (Exception e) {
            logger.warn("Failed to shutdown the blockingTaskExecutor: {}", executor, e);
        }
    }

    final Builder<AccessLogWriter> builder = ImmutableSet.builder();
    config.virtualHosts()
          .stream()
          .filter(VirtualHost::shutdownAccessLogWriterOnStop)
          .forEach(virtualHost -> builder.add(virtualHost.accessLogWriter()));
    config.serviceConfigs()
          .stream()
          .filter(ServiceConfig::shutdownAccessLogWriterOnStop)
          .forEach(serviceConfig -> builder.add(serviceConfig.accessLogWriter()));

    final Set<AccessLogWriter> writers = builder.build();
    final List<CompletableFuture<Void>> completionFutures = new ArrayList<>(writers.size());
    writers.forEach(accessLogWriter -> {
        final CompletableFuture<Void> shutdownFuture = accessLogWriter.shutdown();
        shutdownFuture.exceptionally(cause -> {
            logger.warn("Failed to close the {}:", AccessLogWriter.class.getSimpleName(), cause);
            return null;
        });
        completionFutures.add(shutdownFuture);
    });

    CompletableFutures.successfulAsList(completionFutures, cause -> null)
                      .thenRunAsync(() -> future.complete(null), config.startStopExecutor());
}
 
Example #18
Source File: ReplicationLagTolerantCentralDogma.java    From centraldogma with Apache License 2.0 4 votes vote down vote up
private <T> CompletableFuture<T> executeWithRetries(
        Supplier<CompletableFuture<T>> taskRunner,
        BiPredicate<T, Throwable> retryPredicate,
        int attemptsSoFar) {

    return CompletableFutures.handleCompose(taskRunner.get(), (res, cause) -> {
        final Object currentReplicaHint = currentReplicaHintSupplier.get();
        final int nextAttemptsSoFar = attemptsSoFar + 1;
        final boolean retryRequired = retryPredicate.test(res, cause);
        if (!retryRequired || nextAttemptsSoFar > maxRetries) {
            if (retryRequired) {
                if (currentReplicaHint != null) {
                    logger.warn("[{}] Failed to retrieve the up-to-date data from Central Dogma " +
                                "after {} retries: {} => {}",
                                currentReplicaHint, attemptsSoFar, taskRunner, resultOrCause(res, cause));
                } else {
                    logger.warn("Failed to retrieve the up-to-date data from Central Dogma " +
                                "after {} retries: {} => {}",
                                attemptsSoFar, taskRunner, resultOrCause(res, cause));
                }
            } else if (logger.isDebugEnabled()) {
                if (currentReplicaHint != null) {
                    logger.debug("[{}] Retrieved the up-to-date data after {} retries: {} => {}",
                                 currentReplicaHint, attemptsSoFar, taskRunner, resultOrCause(res, cause));
                } else {
                    logger.debug("Retrieved the up-to-date data after {} retries: {} => {}",
                                 attemptsSoFar, taskRunner, resultOrCause(res, cause));
                }
            }

            if (cause == null) {
                return completedFuture(res);
            } else {
                return exceptionallyCompletedFuture(cause);
            }
        }

        if (logger.isDebugEnabled()) {
            if (currentReplicaHint != null) {
                logger.debug("[{}] Got the out-of-date data ({} attempt(s) so far): {} => {}",
                             currentReplicaHint, nextAttemptsSoFar, taskRunner, resultOrCause(res, cause));
            } else {
                logger.debug("Got the out-of-date data ({} attempt(s) so far): {} => {}",
                             nextAttemptsSoFar, taskRunner, resultOrCause(res, cause));
            }
        }

        final CompletableFuture<T> nextAttemptFuture = new CompletableFuture<>();
        executor().schedule(() -> {
            try {
                executeWithRetries(taskRunner, retryPredicate,
                                   nextAttemptsSoFar).handle((newRes, newCause) -> {
                    if (newCause != null) {
                        nextAttemptFuture.completeExceptionally(newCause);
                    } else {
                        nextAttemptFuture.complete(newRes);
                    }
                    return null;
                });
            } catch (Throwable t) {
                nextAttemptFuture.completeExceptionally(t);
            }
        }, retryIntervalMillis, TimeUnit.MILLISECONDS);

        return nextAttemptFuture;
    }).toCompletableFuture();
}