/**
   * This blocking function attempts to send the message passed in as a parameter. This {@link
   * AmqpsIotHubConnection} handles all calls to this method.
   *
   * <p>Only the first call to this method will result in an attempt to send. Until the message has
   * been sent, all other calls to this method will block. Once a message has been sent and this
   * method notified that it has been sent, this method will be invoked again if was previously
   * another call to send a message.
   *
   * <p>If a message has been passed down to the handler for sending but the message isn't sent
   * after a default constant number of seconds, the {@link AmqpsTransport} will set an ERROR status
   * code on the message and it will placed back onto the queue.
   *
   * @throws IOException If {@link AmqpsIotHubConnectionBaseHandler} has not been initialized.
   */
  protected synchronized void send(Tuple<CompletableFuture<Boolean>, byte[], Object> message)
      throws IOException {
    if (this.state == ReactorState.CLOSED) {
      throw new IllegalStateException(
          "The AMQPS IotHub Connection is currently closed. Call open() before attempting to send a message.");
    }
    if (message != null) {
      if (this.inProgressMessageMap.size() >= this.maxQueueSize * 0.9) {
        message.V1.completeExceptionally(
            new Throwable("Insufficient link credit to send message."));
      } else {
        try {
          // Use the content and ID fields of the input message to have the handler create and send
          // the message
          CompletableFuture<Integer> deliveryFuture =
              amqpsHandler.createBinaryMessage((byte[]) message.V2, message.V3);

          // Wait for a period of time before rejecting the message
          new Thread(
                  () -> {
                    try {
                      Thread.sleep(DEFAULT_DELIVERY_WAIT_TIME_SECONDS * 1000);
                      deliveryFuture.completeExceptionally(
                          new Throwable("Default timeout exceeded before this message was sent."));
                    } catch (InterruptedException e) {
                      e.printStackTrace();
                    }
                  })
              .start();

          // Wait for the deliveryFuture to be completed, providing the delivery hash code.
          // When this future completes, the message has been SENT
          Integer deliveryHash = deliveryFuture.get();
          inProgressMessageMap.put(deliveryHash, message);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        // The message was unable to be sent, exceptionally complete that future causing the message
        // to be put back on the queue.
        catch (ExecutionException e) {
          message.V1.completeExceptionally(e.getCause());
          this.fail(e.getCause());
        }
        // There was some other problem sending, exceptionally complete that future causing the
        // message to be put back on the queue.
        catch (Exception e) {
          if (message != null) {
            message.V1.completeExceptionally(e);
          }
          this.fail(e);
        }
      }
    } else {
      throw new IOException("Cannot send an unitialized message.");
    }
  }
Beispiel #2
0
  @Test
  public void test_findPriceInUSD() {
    Shop s1 = shops.get(0);
    String product = "MacBook 11";

    Future<Double> priceInUSD =
        CompletableFuture.supplyAsync(() -> s.getPrice(product))
            .thenCombine(
                CompletableFuture.supplyAsync(() -> ExchangeService.getRate(USD, FRANC)),
                (price, rate) -> price * rate);
  }
 public Stream<CompletableFuture<String>> findPriceStream(String product) {
   return shops
       .stream()
       .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor))
       .map(future -> future.thenApply(Quote::parse))
       .map(
           future ->
               future.thenCompose(
                   quote ->
                       CompletableFuture.supplyAsync(
                           () -> Discount.applyDiscount(quote), executor)));
 }
  private <T> void retryHelper(
      BiFunction<Integer, Integer, CompletableFuture<T>> function, CompletableFuture<T> result) {
    final int retries = doRetry(function);
    final int index = getNextIndex(function);
    final long start = System.currentTimeMillis();
    if (index > -1) {
      try {
        function
            .apply(index, retries)
            .whenComplete(
                (obj, ex) -> {
                  if (ex == null) {
                    registerSuccess(function, index, start);
                    result.complete(obj);

                  } else {
                    if (retries > 0) {
                      registerFailure(function, index, false);
                      retryHelper(function, result);

                    } else {
                      registerFailure(function, index, true);
                      result.completeExceptionally(ex);
                    }
                  }
                });

      } catch (Exception e) {
        if (retries > 0) {
          registerFailure(function, index, false);
          retryHelper(function, result);

        } else {
          registerFailure(function, index, true);
          result.completeExceptionally(e);
        }
      }

    } else {
      result.completeExceptionally(new LoadBalancerException("All backends suspended"));
    }
  }
 private static void asyncInCompletableFuture() {
   CompletableFuture.supplyAsync(
           () -> {
             for (int i = 0; i < 1000; ++i) {
               if (i % 5 == 0) System.out.println("Doing hard work ....");
             }
             return new File("/tmp/foo");
           })
       .thenApply(File::toPath)
       .thenAccept(System.out::println);
 }
 public void printPricesStream() {
   long start = System.nanoTime();
   CompletableFuture[] futures =
       findPriceStream("myPhone")
           .map(
               f ->
                   f.thenAccept(
                       s ->
                           System.out.println(
                               s
                                   + " (done in "
                                   + ((System.nanoTime() - start) / 1_000_000)
                                   + " msecs)")))
           .toArray(size -> new CompletableFuture[size]);
   CompletableFuture.allOf(futures).join();
 }
  public void stop() {

    if (stopped) {
      throw new RuntimeException("Already stopped or in progress");
    }

    stopped = true;

    CompletableFuture<?>[] futures =
        cachedDispatchQueues
            .values()
            .stream()
            .filter(v -> v != null)
            .toArray(CompletableFuture<?>[]::new);

    CompletableFuture.allOf(futures).join();

    service.shutdown();
  }
  @Override
  @SuppressWarnings("unchecked")
  public CompletableFuture<Void> dispatchAsync(String dispatchId, Runnable task) {

    try {
      return (CompletableFuture<Void>)
          cachedDispatchQueues.compute(
              dispatchId,
              (k, queue) -> {
                CompletableFuture<Void> voidCompletableFuture =
                    (queue == null)
                        ? CompletableFuture.runAsync(task)
                        : ((CompletableFuture<Void>) queue).thenRunAsync(task);
                return voidCompletableFuture;
              });
    } catch (Throwable t) {
      log.warn(
          "Exception thrown when calling dispatchAngGetFuture for dispatchId[{}]", dispatchId, t);
      throw t;
    }
  }
  @Override
  public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
    if (r instanceof RunnableScheduledFuture) {
      Object callable = ReflectionUtil.getFieldValue(r, "callable");
      Object cfAsync = ReflectionUtil.getFieldValue(callable, "task");
      r = (Runnable) cfAsync;
    }

    if (r instanceof ForkJoinTask && r.toString().contains("CompletableFuture$Async")) {
      Field field = ReflectionUtil.getField(r, "dst"); // jdk8u20
      if (field == null) {
        field = ReflectionUtil.getField(r, "dep"); // jdk8u40
      }
      Object dst = ReflectionUtil.getFieldValue(r, field);
      if (dst instanceof CompletableFuture) {
        ((CompletableFuture) dst).cancel(false);
        log.debug("Canceled completable future {}", r);
      }
    } else if (r instanceof Future) {
      ((Future) r).cancel(false);
      log.debug("Canceled future {}", r);
    }
  }