首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AsyncHttpClient和超时

AsyncHttpClient和超时
EN

Stack Overflow用户
提问于 2012-11-29 18:44:33
回答 2查看 4.3K关注 0票数 2

在AsyncHttpClient JDKFuture.get()中

代码语言:javascript
复制
 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);
            }

为什么我们有两个超时?

代码语言:javascript
复制
  1. timeout as param
  2. responseTimeoutInMs

第二个超时正在伤害我们,因为调用即使在超时到期后也不会出现。它不断递归地再次调用get()。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-07 04:04:49

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

代码语言:javascript
复制
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上找到一个人可以解释这个实现背后的原理,如果有的话。您必须直接询问该代码的支持者/作者。

票数 3
EN

Stack Overflow用户

发布于 2016-01-08 20:20:04

不要使用JDK提供程序,它已经损坏,并将在AHC2中删除。使用Netty提供程序,并升级到最新版本。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13623995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档