Home > front end >  Edited: Retrofit and CompletableFuture, is there a way to not rely on the underlying connection pool
Edited: Retrofit and CompletableFuture, is there a way to not rely on the underlying connection pool

Time:05-07

Original question:

OkHttp, is there a way to not rely on a connection pool?

Hey OkHttp users and/or contributors!

Is there a way to use an OkHttpClient without any pool of connections ? That is, in other words, is it possibile to fire one or a few HTTP request from the same thread in which myClient.execute() method is invoked?

I tried to find a clear answer online but this is all I found:

  • by default a connection pool is used, and as such my understanding is that an HTTP request will be always fired from one of the threads that are instantiated and kept alive by the OkHttp client
  • It’s possible to configure a custom ExecutorService at the client level. Theoretically, I could define a single threaded executor, but that would anyway come with a dedicated extra thread (and not the parent one in my invocation stack). moreover, such a “solution” would be impractical as it would cause queuing issues under a non negligible load, assuming a singleton instance of the client is being used.

I could not find a way to take over parallelism at the Request level. The only workaround I can currently think of is as follows:

  • single threaded executor setup
  • Multiple client instances, each for any request (or set of requests of the same functional flow)

The above would anyway not solve my problem completely, as there is anyway an extra thread per request/s. Moreover, based on the documentation I found online the shared best practice when using OkHttp is to share a singleton client instance amongst multiple threads.

Thanks a lot!

Ps: for context, the reason I’m asking is that ~a customer~ a friend of mine has a logger implementation that relies on ThreadLocals to correlate HTTP requests logs, produced by the client instance via an application interceptor. They’re replacing their existing, vintage integration with my company payments API with a brand new SDK we’re offering, that arguably deals with concurrency differently from what they were used.

Edits

enter image description here

Wrt the above screenshot, we can see that one of OkHttp threads is used. That said, I still do have doubts in cases where there are requests fired in the context of interceptors. In my tests, in those cases requests are fired from the main thread.

  1. Is the connection pool always used, irregardless of sync or async calls ?

Yes. I can see the connection pool being invoked in both cases. below a sample in a sync use case: enter image description here

  1. Right to say that the Dispatcher is only relevant with async flows ?

No, whilst I'd say its executor service is only used in case of async flows, the dispatcher also keeps track of sync calls in flight. Async flows are managed in the context of a private boolean promoteAndExecute() method:

for (int i = 0, size = executableCalls.size(); i < size; i  ) {
      AsyncCall asyncCall = executableCalls.get(i);
      asyncCall.executeOn(executorService());
    }

The same dispatcher keeps track of sync calls in a runningSyncCalls instance variable. That being said, I think that if one plans to use OKhttp/Retrofit in a synchronous fashion only, it makes sense to limit the amount of threads in the Dispatcher used. The default one is probably a good fit already

  • Related