2

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

タイムアウトの期限が切れても通話が発信されないため、2回目のタイムアウトは私たちを傷つけています。get()を再帰的に呼び出し続けます。

responseTimeoutInMsがヒットすると、接続は閉じられますか?タイムアウトより低く設定しようとしています。

4

2 に答える 2

3

私がネットで見つけた方法を参照していると思います。

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にいるとは思わない。そのコードのサポーター/作者に直接尋ねる必要があります。

于 2013-11-06T20:04:49.390 に答える
0

JDKプロバイダーは使用しないでください。壊れており、AHC 2にドロップされています。Nettyプロバイダーを使用して、最新バージョンにアップグレードしてください。

于 2016-01-08T12:20:03.697 に答える