2012-11-29 80 views
2

在AsyncHttpClient JDKFuture.get()AsyncHttpClient和超時

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

我假設你是指我在網上找到的方法:

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合同。即使Future代表的任務仍在運行,正確的行爲也會讓get方法超時。

但遞歸調用get方法是一個雙重故障。作爲小超時值的遞歸不僅危險,可能導致StackOverflowError;再次傳遞相同的timeout意味着無限地推遲超時,因爲每次重新調用都會將該值視爲相對於當前時間。

有趣的是,即使方法達到了超時點,它也會將TimeoutException包裹在ExecutionException內,從而向調用者報告完全錯誤的語義。

我不相信你會發現有人在stackoverflow誰可以解釋這個實現背後的理由,如果有一個。你將不得不直接詢問該代碼的支持者/作者。

+0

感謝您的解釋 - 看起來就像我們可以在沒有作者幫助的情況下一樣。 – Fakrudeen

0

不要使用JDK提供程序,它已損壞並正在AHC 2中丟棄。使用Netty one,並升級到現代版本。

+0

現有的(除了上面的問題之外)破了什麼? –

+0

它總是一種從未被任何提交者使用過的玩具。它沒有維護,缺少大多數功能,除了那些沒有意識到必須提供Netty或Grizzly等提供者的人以外,沒有人使用它。 AHC 2將完全建立在Netty之上。 –