Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #810 from shintasmith/fix_ttl_test_ubuntu16
create a datastax RetryPolicy that can retry n times
- Loading branch information
Showing
6 changed files
with
188 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
blueflood-core/src/main/java/com/rackspacecloud/blueflood/io/datastax/RetryNTimes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.rackspacecloud.blueflood.io.datastax; | ||
|
||
import com.datastax.driver.core.Cluster; | ||
import com.datastax.driver.core.exceptions.DriverException; | ||
import com.datastax.driver.core.policies.RetryPolicy; | ||
import com.datastax.driver.core.ConsistencyLevel; | ||
import com.datastax.driver.core.Statement; | ||
import com.datastax.driver.core.WriteType; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* A class that retry on read/write/unavailable timeouts n times, where | ||
* n is a configurable number | ||
*/ | ||
public class RetryNTimes implements RetryPolicy { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(RetryNTimes.class); | ||
private final int readAttempts; | ||
private final int writeAttempts; | ||
private final int unavailableAttempts; | ||
|
||
/** | ||
* A Datastax {@link RetryPolicy} that is capable of retrying n times | ||
* @param readAttempts | ||
* @param writeAttempts | ||
* @param unavailableAttempts | ||
*/ | ||
public RetryNTimes(int readAttempts, int writeAttempts, int unavailableAttempts) { | ||
this.readAttempts = readAttempts; | ||
this.writeAttempts = writeAttempts; | ||
this.unavailableAttempts = unavailableAttempts; | ||
} | ||
|
||
@Override | ||
public RetryDecision onReadTimeout(Statement stmnt, ConsistencyLevel cl, | ||
int requiredResponses, int receivedResponses, | ||
boolean dataReceived, int rTime) { | ||
if (dataReceived) { | ||
return RetryDecision.ignore(); | ||
} else if (rTime < readAttempts) { | ||
LOG.info(String.format("Retrying on ReadTimeout: stmnt %s, " + | ||
"consistency %s, requiredResponse %d, " + | ||
"receivedResponse %d, dataReceived %s, rTime %d", | ||
stmnt, cl, requiredResponses, receivedResponses, dataReceived, rTime)); | ||
return RetryDecision.retry(cl); | ||
} else { | ||
return RetryDecision.rethrow(); | ||
} | ||
|
||
} | ||
|
||
@Override | ||
public RetryDecision onWriteTimeout(Statement stmnt, ConsistencyLevel cl, | ||
WriteType wt, int requiredResponses, | ||
int receivedResponses, int wTime) { | ||
if (wTime < writeAttempts) { | ||
LOG.info(String.format("Retrying on WriteTimeout: stmnt %s, " + | ||
"consistency %s, writeType %s, requiredResponse %d, " + | ||
"receivedResponse %d, rTime %d", | ||
stmnt, cl, wt.toString(), requiredResponses, receivedResponses, wTime)); | ||
return RetryDecision.retry(cl); | ||
} | ||
return RetryDecision.rethrow(); | ||
} | ||
|
||
@Override | ||
public RetryDecision onUnavailable(Statement stmnt, ConsistencyLevel cl, | ||
int requiredResponses, int receivedResponses, int uTime) { | ||
if (uTime < unavailableAttempts) { | ||
LOG.info(String.format("Retrying on unavailable: stmnt %s, consistency %s, " + | ||
"requiredResponse %d, receivedResponse %d, rTime %d", | ||
stmnt, cl, requiredResponses, receivedResponses, uTime)); | ||
return RetryDecision.retry(ConsistencyLevel.ONE); | ||
} | ||
return RetryDecision.rethrow(); | ||
} | ||
|
||
@Override | ||
public RetryDecision onRequestError(Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { | ||
LOG.info(String.format("Trying nextHost on requestError: stmnt %s, consistency %s, driver ex %s, nbRetry %d", | ||
statement, cl, e, nbRetry)); | ||
return RetryDecision.tryNextHost(cl); | ||
} | ||
|
||
@Override | ||
public void init(Cluster cluster) { | ||
} | ||
|
||
@Override | ||
public void close() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
blueflood-core/src/test/java/com/rackspacecloud/blueflood/io/datastax/RetryNTimesTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.rackspacecloud.blueflood.io.datastax; | ||
|
||
import com.datastax.driver.core.ConsistencyLevel; | ||
import com.datastax.driver.core.Statement; | ||
import com.datastax.driver.core.WriteType; | ||
import com.datastax.driver.core.policies.RetryPolicy; | ||
import org.junit.Test; | ||
|
||
import static org.mockito.Mockito.mock; | ||
import static org.junit.Assert.*; | ||
|
||
/** | ||
* Unit test for RetryNTimes policy | ||
*/ | ||
public class RetryNTimesTest { | ||
|
||
@Test | ||
public void firstTimeRetryOnReadTimeout_shouldRetry() throws Exception { | ||
RetryNTimes retryPolicy = new RetryNTimes(3, 3, 3); | ||
Statement mockStatement = mock( Statement.class ); | ||
RetryPolicy.RetryDecision retryResult = retryPolicy.onReadTimeout(mockStatement, ConsistencyLevel.LOCAL_ONE, 1, 0, false, 0); | ||
RetryPolicy.RetryDecision retryExpected = RetryPolicy.RetryDecision.retry(ConsistencyLevel.LOCAL_ONE); | ||
assertRetryDecisionEquals(retryExpected, retryResult); | ||
} | ||
|
||
@Test | ||
public void maxTimeRetryOnReadTimeout_shouldRethrow() throws Exception { | ||
RetryNTimes retryPolicy = new RetryNTimes(3, 3, 3); | ||
Statement mockStatement = mock( Statement.class ); | ||
|
||
RetryPolicy.RetryDecision retryResult = retryPolicy.onReadTimeout(mockStatement, ConsistencyLevel.LOCAL_ONE, 1, 0, false, 3); | ||
RetryPolicy.RetryDecision retryExpected = RetryPolicy.RetryDecision.rethrow(); | ||
assertRetryDecisionEquals(retryExpected, retryResult); | ||
} | ||
|
||
@Test | ||
public void firstTimeRetryOnWriteTimeout_shouldRetry() throws Exception { | ||
RetryNTimes retryPolicy = new RetryNTimes(3, 3, 3); | ||
Statement mockStatement = mock( Statement.class ); | ||
RetryPolicy.RetryDecision retryResult = retryPolicy.onWriteTimeout(mockStatement, ConsistencyLevel.LOCAL_ONE, WriteType.BATCH, 1, 0, 0); | ||
RetryPolicy.RetryDecision retryExpected = RetryPolicy.RetryDecision.retry(ConsistencyLevel.LOCAL_ONE); | ||
assertRetryDecisionEquals(retryExpected, retryResult); | ||
} | ||
|
||
@Test | ||
public void maxTimeRetryOnWriteTimeout_shouldRethrow() throws Exception { | ||
RetryNTimes retryPolicy = new RetryNTimes(3, 3, 3); | ||
Statement mockStatement = mock( Statement.class ); | ||
|
||
RetryPolicy.RetryDecision retryResult = retryPolicy.onWriteTimeout(mockStatement, ConsistencyLevel.LOCAL_ONE, WriteType.BATCH, 1, 0, 3); | ||
RetryPolicy.RetryDecision retryExpected = RetryPolicy.RetryDecision.rethrow(); | ||
assertRetryDecisionEquals(retryExpected, retryResult); | ||
} | ||
|
||
@Test | ||
public void firstTimeRetryOnUnavailable_shouldRetry() throws Exception { | ||
RetryNTimes retryPolicy = new RetryNTimes(3, 3, 3); | ||
Statement mockStatement = mock( Statement.class ); | ||
RetryPolicy.RetryDecision retryResult = retryPolicy.onUnavailable(mockStatement, ConsistencyLevel.LOCAL_ONE, 1, 0, 0); | ||
RetryPolicy.RetryDecision retryExpected = RetryPolicy.RetryDecision.retry(ConsistencyLevel.ONE); | ||
assertRetryDecisionEquals(retryExpected, retryResult); | ||
} | ||
|
||
@Test | ||
public void maxTimeRetryOnUnavailable_shouldRethrow() throws Exception { | ||
RetryNTimes retryPolicy = new RetryNTimes(3, 3, 3); | ||
Statement mockStatement = mock( Statement.class ); | ||
|
||
RetryPolicy.RetryDecision retryResult = retryPolicy.onUnavailable(mockStatement, ConsistencyLevel.LOCAL_ONE, 1, 0, 3); | ||
RetryPolicy.RetryDecision retryExpected = RetryPolicy.RetryDecision.rethrow(); | ||
assertRetryDecisionEquals(retryExpected, retryResult); | ||
} | ||
|
||
private void assertRetryDecisionEquals(RetryPolicy.RetryDecision expected, RetryPolicy.RetryDecision result) { | ||
assertEquals("first time retry type", expected.getType(), result.getType()); | ||
assertEquals("first time retry consistency level", expected.getRetryConsistencyLevel(), result.getRetryConsistencyLevel()); | ||
assertEquals("first time retry current", expected.isRetryCurrent(), result.isRetryCurrent()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters