All Downloads are FREE. Search and download functionalities are using the official Maven repository.

feign.AsyncClient Maven / Gradle / Ivy

/*
 * Copyright 2012-2023 The Feign Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package feign;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import feign.Request.Options;

/**
 * Submits HTTP {@link Request requests} asynchronously, with an optional context.
 */
@Experimental
public interface AsyncClient {

  /**
   * Executes the request asynchronously. Calling {@link CompletableFuture#cancel(boolean)} on the
   * result may cause the execution to be cancelled / aborted, but this is not guaranteed.
   *
   * @param request safe to replay
   * @param options options to apply to this request
   * @param requestContext - the optional context, for example for storing session cookies. The
   *        client should update this appropriately based on the received response before completing
   *        the result.
   * @return a {@link CompletableFuture} to be completed with the response, or completed
   *         exceptionally otherwise, for example with an {@link java.io.IOException} on a network
   *         error connecting to {@link Request#url()}.
   */
  CompletableFuture execute(Request request, Options options, Optional requestContext);

  class Default implements AsyncClient {

    private final Client client;
    private final ExecutorService executorService;

    public Default(Client client, ExecutorService executorService) {
      this.client = client;
      this.executorService = executorService;
    }

    @Override
    public CompletableFuture execute(Request request,
                                               Options options,
                                               Optional requestContext) {
      final CompletableFuture result = new CompletableFuture<>();
      final Future future = executorService.submit(() -> {
        try {
          result.complete(client.execute(request, options));
        } catch (final Exception e) {
          result.completeExceptionally(e);
        }
      });
      result.whenComplete((response, throwable) -> {
        if (result.isCancelled()) {
          future.cancel(true);
        }
      });
      return result;
    }
  }

  /**
   * A synchronous implementation of {@link AsyncClient}
   *
   * @param  - unused context; synchronous clients handle context internally
   */
  class Pseudo implements AsyncClient {

    private final Client client;

    public Pseudo(Client client) {
      this.client = client;
    }

    @Override
    public CompletableFuture execute(Request request,
                                               Options options,
                                               Optional requestContext) {
      final CompletableFuture result = new CompletableFuture<>();
      try {
        result.complete(client.execute(request, options));
      } catch (final Exception e) {
        result.completeExceptionally(e);
      }

      return result;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy