Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

investigate async http client integration #24

Open
codefromthecrypt opened this issue Jul 16, 2013 · 13 comments
Open

investigate async http client integration #24

codefromthecrypt opened this issue Jul 16, 2013 · 13 comments
Labels
enhancement For recommending new capabilities feign-12 Issues that are related to the next major release proposal Proposed Specification or API change

Comments

@codefromthecrypt
Copy link
Contributor

Per a discussion with @NiteshKant, I believe we can make a compatible http response callback interface to facilitate nio support.

Context

Many async http clients provide a callback interface such as below

Future<Integer> f = asyncHttpClient.prepareGet("http://www.ning.com/").execute(
   new AsyncCompletionHandler<Integer>(){

    @Override
    public Integer onCompleted(Response response) throws Exception{
        // Do something with the Response
        return response.getStatusCode();
    }

    @Override
    public void onThrowable(Throwable t){
        // Something wrong happened.
    }
});

https://github.com/AsyncHttpClient/async-http-client

How

It should be possible to extend our Client to be compatible with the callback system from one or more async http clients, avoiding the need to independently manage threads in Feign.

ex.

interface Client {
  // existing
  Response execute(Request request, Options options) throws IOException;
  // new
  void execute(Request request, Options options, IncrementalCallback<Response> responseCallback);

An asynchronous client would need to map their callback to ours.

Any synchronous http client (including our default) could extend from a base class that implements the callback method like so

void execute(Request request, Options options, IncrementalCallback<Response> responseCallback) {
      httpExecutor.get().execute(new Runnable() {
        @Override public void run() {
          Error error = null;
          try {
            responseCallback.onNext(execute(request, options));
            responseCallback.onSuccess();
          } catch (Error cause) {
            // assign to a variable in case .onFailure throws a RTE
            error = cause;
            responseCallback.onFailure(cause);
          } catch (Throwable cause) {
            responseCallback.onFailure(cause);
          } finally {
            Thread.currentThread().setName(IDLE_THREAD_NAME);
            if (error != null)
              throw error;
          }
        }
      }
  }
@codefromthecrypt
Copy link
Contributor Author

cc @benjchristensen

@benjchristensen
Copy link

That makes sense, with IncrementalCallback we can support both blocking and non-blocking IO.

@benjchristensen
Copy link

Is there a reason to keep the synchronous method?

// existing
  Response execute(Request request, Options options) throws IOException;

@codefromthecrypt
Copy link
Contributor Author

yes because most api interactions with http are still synchronous and we
don't want to or need to eliminate "easy mode" just to facilitate advanced.

@codefromthecrypt
Copy link
Contributor Author

for example, implementing Client with url connection (a synchronous client) could reuse a base implementation of forking off the request. I've in the past made the mistake of forcing synchronous http calls through blocking futures (jclouds), and don't want to repeat that as a default, particularly as it would require sync calls to unnecessarily fire threads.

Having an interface that supports both means allows folks to decide at configuration time how they prefer to interact, whether that's making everything block on futures, use real async tasks or use async only when asked.

@aansel
Copy link

aansel commented Aug 28, 2014

Any update on this? Are you still planning to integrate this in a future release?
Thanks.

@kflorence
Copy link

Please implement support for async, it's a pretty big drawback right now when your client and MVC controller can't share the same contract because of the use of (for example) DeferredResult.

@codefromthecrypt
Copy link
Contributor Author

DeferredResult is a spring MVC type, right? If that's the goal, maybe
raise an issue in spring-cloud-netflix where the MVC contract lives?

@kflorence
Copy link

@adriancole Yes, it is a spring MVC type, however, if the underlying implementation doesn't support async I don't see how spring-cloud-netflix would be able to solve the problem. I will take your suggestion and raise an issue there, though, in the hopes that maybe there is a workaround. Thanks for the quick response!

@rstml
Copy link

rstml commented Mar 15, 2016

+1. It's quite strange that popular general purpose HTTP client doesn't support async.

@codefromthecrypt
Copy link
Contributor Author

codefromthecrypt commented Mar 16, 2016 via email

@rstml
Copy link

rstml commented Mar 16, 2016

I see. Actually planning to use Hystrix w/ Rx. However what concerns me is the lack of non-blocking client support. Maybe I'm missing something, but it seems that Feign uses either Apache HttpClient or OkHttp - both in blocking mode? Was hoping that Async HttpClient would allow me to do non-blocking requests.

@codefromthecrypt
Copy link
Contributor Author

codefromthecrypt commented Mar 16, 2016 via email

@kdavisk6 kdavisk6 added the enhancement For recommending new capabilities label Jul 20, 2018
@kdavisk6 kdavisk6 removed this from the 3.1.0 milestone Nov 19, 2018
@kdavisk6 kdavisk6 added the proposal Proposed Specification or API change label Aug 7, 2019
@kdavisk6 kdavisk6 added the feign-12 Issues that are related to the next major release label Dec 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement For recommending new capabilities feign-12 Issues that are related to the next major release proposal Proposed Specification or API change
Projects
None yet
Development

No branches or pull requests

6 participants