编辑:改装和完整的未来,是否有办法不依靠基础连接池?

发布于 2025-01-24 23:12:02 字数 1958 浏览 3 评论 0原文

原始问题:

okhttp,有没有办法不依赖连接池?

嘿,Okhttp用户和/或贡献者!

有没有办法使用没有任何连接池的OkhttpClient?也就是说,换句话说,是否可以从同一线程中启动一个或几个http请求,其中myclient.execute()方法被调用?

我试图在网上找到一个明确的答案,但这是我发现的:

  • 默认情况下,使用了一个连接池,因此我的理解是,HTTP请求将始终从实例化并保持生存的一个线程中触发。 OKHTTP客户端
  • 可以在客户端级别配置自定义执行权限服务。从理论上讲,我可以定义一个线程执行程序,但无论如何,这将带有一个专用的额外线程(而不是我的调用堆栈中的父母)。此外,这样的“解决方案”将是不切实际的,因为假设使用了客户的单例实例,它将在不容易忽略的负载下引起排队问题。

我找不到在请求级别接管平行的方法。我当前能想到的唯一解决方法如下:

  • 单程螺纹执行程序设置
  • 多个客户端实例,每个请求(或同一功能流的一组请求)

上面都无法完全解决我的问题,因为无论如何都有一个每个请求/s的额外线程。此外,根据我在线发现的文档,使用OKHTTP时共享的最佳实践是在多个线程中共享单身客户端实例。

多谢!

PS:对于上下文,我问的原因是〜客户〜我的一个朋友具有依赖threadlocal s的记录器实现,以相关联HTTP请求日志,该请求日志,由客户端实例生成应用程序拦截器。他们正在用我们提供的全新SDK代替现有的老式集成与我的公司Dayments API,可以说,该款项与使用与使用方式不同。

编辑

此答复揭示了我最初的问题: 是的,只需使用execute()方法call> call> call type即可通过execute()方法,可以同步在主线程上使用OKHTTP。

我正在遇到的行为(所有调用到线程池中)是由于我将改造和完整的future< t>声明为我的REST API端点的响应类型。例如:

@GET("/payments/{id}")
    CompletableFuture<ApiResponse<PaymentDetail>> getPayment(@Path("id") String paymentId);

实际上,在我的特殊情况下,我也是一个自定义调用适配器,可以适应A appletableFuture&lt; t&gt; appletablefuture&lt; apiresponse&lt; t&gt;改进的错误处理,但是在此范围内,此不应相关

最终,我的出色问题是:

  1. 当使用Raturofit的完整图适配器时,这如何影响OKHTTP多线程?换句话说,我的理解是正确的,当处理Retrofit中的完整Future的响应元件时,我们始终将HTTP请求提交给OkhttpClient中可用的一个线程 dispatcher
  2. 我是对的是,无论在Raterofit/Okhttp上使用的同步或异步模型如何,OKHTTP的连接池总是被使用?
  3. 可以说,使用同步模型时,Okhttp的调度程序(甚至默认一个)是无关紧要的?如果是这样,是否有办法没有OKHTTP提供任何线程池?

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

This reply shed a light on the original question I had:
Yes, it's possible to use OkHttp synchronously on the main thread, by just using the execute() method offered by the Call type.

The behavior I'm experiencing (all calls submitted to a thread pool) is due to the fact that I'm using Retrofit along with CompletableFuture<T>s declared as response types of my REST API endpoints. For instance:

@GET("/payments/{id}")
    CompletableFuture<ApiResponse<PaymentDetail>> getPayment(@Path("id") String paymentId);

Actually, in my particular case I've also a custom call adapter that adapts a CompletableFuture<T> into a CompletableFuture<ApiResponse<T>> for an improved error handling, but this should not be relevant in this scope.

My outstanding questions are, eventually:

  1. When using Retrofit's CompletableFuture adapter, how that affects Okhttp multithreading ? In other words, is my understanding correct that when dealing with responsens of CompletableFuture in Retrofit, we always submit the HTTP request to one of the threads that's available in the OkhttpClient Dispatcher ?
  2. Am I right in saying that regardless of the synchronous or asynchronous model used on Retrofit/OkHttp, OkHttp's connection pool is always being used ?
  3. Is it right to say that when using a synchronous model, OkHttp's Dispatcher (even the default one) is irrelevant ? If so, is there a way to not have any thread pool provisioned by OkHttp ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦中楼上月下 2025-01-31 23:12:02

如果使用call.execute(),几乎所有工作都会发生在使该调用的线程上。这包括所有拦截器。

If you use Call.execute(), almost all work happens on the thread that makes that call. This includes all interceptors.

怪我入戏太深 2025-01-31 23:12:02

我做了一些特定的测试来回答我的问题。

  1. 在改造中使用完整的未来是否意味着我们依靠内部OKHTTP线程池?

是的,按照我的测试。

wrt上面的屏幕截图,我们可以看到使用了一个OKHTTP线程。
也就是说,在拦截器的背景下提出请求的情况下,我仍然有疑问。在我的测试中,在这种情况下,请求从主线程发射。

  1. 连接池是否总是使用,无权同步或异步调用?

是的。在两种情况下,我都可以看到连接池都被调用了。在同步用例中的样本下方:

  1. dispatcher仅与异步流有关的权利?

不,虽然我会说其执行器服务仅在异步流中使用,但调度员还可以跟踪飞行中的同步呼叫。
异步流是在私有boolean proporteandexecute()方法的上下文中管理的:

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

同一调度程序在runningsynccalls实例变量中跟踪同步调用。
话虽这么说,我认为,如果只计划以同步方式使用OKHTTP/改造,那么限制所使用的调度程序中的线程量是有意义的。默认一个可能已经很合适

I did some specific tests to answer my questions.

  1. Does the use of CompletableFuture on Retrofit mean that we're relying on the internal OkHttp Thread pool ?

Yes, as per my tests.
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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文