简体   繁体   English

AsyncHttpClient 和超时

[英]AsyncHttpClient and timeouts

In AsyncHttpClient JDKFuture.get()在 AsyncHttpClient JDKFuture.get()

 public V  [More ...] get(long timeout, TimeUnit unit)  {
        V content = null;
        try {
            if (innerFuture != null) {
                content = innerFuture.get(timeout, unit);
            }
        } catch (TimeoutException t) {
            if (!contentProcessed.get() && timeout != -1 && 
              ((System.currentTimeMillis() -   touch.get()) <= responseTimeoutInMs)) {
                return get(timeout, unit);
            }

Why do we have 2 timeouts?为什么我们有 2 次超时?

  1. timeout as param
  2. responseTimeoutInMs

Second timeout is hurting us, as the call doesn't comeout even after timeout expires.第二次超时正在伤害我们,因为即使超时到期后调用也不会出现。 It keeps calling get() again recursively.它继续递归调用 get() 。

Will the connection get closed once responseTimeoutInMs is hit?一旦 responseTimeoutInMs 被击中,连接会关闭吗? We are trying to set it to lower than timeout.我们试图将其设置为低于超时时间。

I assume you are referring to the method I found in the net:我假设您指的是我在网上找到的方法:

public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    V content = null;
    try {
        if (innerFuture != null) {
            content = innerFuture.get(timeout, unit);
        }
    } catch (TimeoutException t) {
        if (!contentProcessed.get() && timeout != -1 && ((System.currentTimeMillis() - touch.get()) <= responseTimeoutInMs)) {
            return get(timeout, unit);
        }

        if (exception.get() == null) {
            timedOut.set(true);
            throw new ExecutionException(new TimeoutException(String.format("No response received after %s", responseTimeoutInMs)));
        }
    } catch (CancellationException ce) {
    }

    if (exception.get() != null) {
        throw new ExecutionException(exception.get());
    }
    return content;
}

You can consider this class as being erroneous in several regards.你可以认为这个类在几个方面是错误的。 The first mistake which jumps directly into the eye is the use of System.currentTimeMillis() instead of System.nanoTime() .第一个直接进入眼睛的错误是使用System.currentTimeMillis()而不是System.nanoTime() System.currentTimeMillis() refers to the computers system clock which may be adjusted during the programs execution and hence can jump back and forth. System.currentTimeMillis()是指计算机系统时钟,在程序执行过程中可以调整,因此可以来回跳转。 Code dealing with timeouts should use System.nanoTime() which gives a value relative to the programs execution independent to the real world clock.处理超时的代码应该使用System.nanoTime() ,它给出一个相对于独立于现实世界时钟的程序执行的值。

responseTimeoutInMs seems to be meant as a connection timeout but using it even when the timeout passed as parameter value has been expired is a violation of the Future contract. responseTimeoutInMs似乎意味着连接超时,但即使在作为参数值传递的timeout已过期时使用它也违反了Future合同。 The correct behavior would be letting the get method time out even when the task represented by the Future may be still running.正确的行为是让get方法超时,即使Future表示的任务可能仍在运行。

But invoking the get method recursively is a double fault.但是递归调用get方法是一个双重错误。 Not only is the recursion dangerous as small timeout values may lead to a StackOverflowError ;递归不仅危险,因为小的超时值可能会导致StackOverflowError passing the same timeout again to itself means deferring the time out infinitely as every re-invocation will treat that value as relative to the current time.再次向自身传递相同的timeout意味着无限推迟timeout ,因为每次重新调用都会将该值视为相对于当前时间。

Interestingly, even if the method gets to the point of timing out it will wrap the TimeoutException inside an ExecutionException reporting a completely wrong semantic to the caller.有趣的是,即使该方法达到超时点,它也会将TimeoutException包装在ExecutionException ,向调用者报告完全错误的语义。

I don't believe that you will find someone on stackoverflow who can explain the rationale behind this implementation, if there is one at all.我不相信你会在 stackoverflow 上找到可以解释这个实现背后的基本原理的人,如果有的话。 You will have to ask the supporter/authors of that code directly.您将不得不直接询问该代码的支持者/作者。

不要使用 JDK 提供程序,它已损坏并且正在 AHC 2 中删除。使用 Netty 一个,并升级到现代版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM