AsyncHttpClient和超时

时间:2012-11-29 10:44:33

标签: java asynchttpclient

在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);
            }

为什么我们有2次超时?

  1. timeout as param
  2. responseTimeoutInMs

第二次超时对我们造成伤害,因为即使在超时到期后呼叫也没有出现。它不断递归地调用get()。

一旦命中了responseTimeoutInMs,连接是否会关闭?我们试图将其设置为低于超时。

2 个答案:

答案 0 :(得分:2)

我假设你指的是我在网上找到的方法:

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;
}

您可以将此课程视为在某些方面存在错误。直接跳入眼睛的第一个错误是使用System.currentTimeMillis()代替System.nanoTime()System.currentTimeMillis()指的是可以在程序执行期间调整的计算机系统时钟,因此可以来回跳转。处理超时的代码应使用System.nanoTime(),它提供与程序执行相关的值,与实际时钟无关。

responseTimeoutInMs似乎意味着连接超时,但即使在参数值作为参数值传递的timeout过期时使用它也违反了Future合同。正确的行为是,即使get所代表的任务可能仍在运行,Future方法也会超时。

但递归调用get方法是一个双重错误。递归不仅危险,因为小超时值可能导致StackOverflowError;再次传递相同的timeout意味着无限延迟时间,因为每次重新调用都会将该值视为相对于当前时间。

有趣的是,即使该方法达到超时点,它也会将TimeoutException包裹在ExecutionException内,向调用者报告一个完全错误的语义。

我不相信你会发现stackoverflow上有人可以解释这个实现背后的基本原理,如果有的话。您将不得不直接询问该代码的支持者/作者。

答案 1 :(得分:0)

不要使用JDK提供商,它已被破坏并被放入AHC 2.使用Netty,并升级到现代版本。