2014-04-10 23 views
2

我想了解增量退避在Java Couchbase API中的工作原理。以下代碼片段來自Couchbase Java Tutorial(我添加了一些評論)。使用Java API的Couchbase退避

public OperationFuture<Boolean> contSet(String key, 
             int exp, 
             Object value, 
             int tries) { 
    OperationFuture<Boolean> result = null; 
    OperationStatus status; 
    int backoffexp = 0; 

    try { 
    do { 
     if (backoffexp > tries) { 
     throw new RuntimeException("Could not perform a set after " 
       + tries + " tries."); 
     } 
     result = cbc.set(key, exp, value); 
     status = result.getStatus(); // Is this a blocking call? 
     if (status.isSuccess()) { 
     break; 
     } 
     if (backoffexp > 0) { 
     double backoffMillis = Math.pow(2, backoffexp); 
     backoffMillis = Math.min(1000, backoffMillis); // 1 sec max 
     Thread.sleep((int) backoffMillis); 
     System.err.println("Backing off, tries so far: " + backoffexp); 
     } 
     backoffexp++; 

     // Why are we checking again if the operation previously failed 
     if (!status.isSuccess()) { 
     System.err.println("Failed with status: " + status.getMessage()); 
     } 

    // If we break on success, why not do while(true)? 
    } while (status.getMessage().equals("Temporary failure")); 
    } catch (InterruptedException ex) { 
    System.err.println("Interrupted while trying to set. Exception:" 
      + ex.getMessage()); 
    } 

    if (result == null) { 
    throw new RuntimeException("Could not carry out operation."); 
    } 

    return result; 
} 

只有在操作成功或失敗時纔會調用getStatus()嗎? (即同步)。 Java Tutorial似乎說它是阻止,但Java API說:

獲取此操作的當前狀態。請注意,操作狀態可能會隨着操作的嘗試而改變,並可能會針對由NodeLocator指定的服務器重試。

爲什麼我們需要多次檢查status.isSuccess()?如果它成功了,我們會打破循環,我們可以認爲它已經失敗了?

如果有任何理由做while (status.getMessage().equals("Temporary failure"))而不是while(true),因爲我們在狀態成功時調用break

感謝

回答

0

getStatus()迫使未來完成(即內部調用get(),所以操作的狀態可以是已知的。換一種方式,有作爲沒有這樣的事情正在申請中的狀態APU,所以您必須強制未來完成對能夠確定的是狀態。

Operation_Future:getStatus的源代碼的詳細信息。

+0

感謝您的。已經失敗(即未破圈外),有沒有什麼好的理由呢示例代碼再次調用'isSuccess()'? – ChrisSSocha