@Override public RetryDecision onReadTimeout(Statement statement, ConsistencyLevel cl, int requiredResponses, int receivedResponses, boolean dataRetrieved, int nbRetry) { if (nbRetry == m_retryCount) return RetryDecision.rethrow(); else { int count = m_readRetries.incrementAndGet(); return RetryDecision.tryNextHost(cl); } }
@Override public RetryDecision onUnavailable(Statement statement, ConsistencyLevel cl, int requiredReplica, int aliveReplica, int nbRetry) { if (nbRetry == m_retryCount) return RetryDecision.rethrow(); else { m_unavailableRetries.incrementAndGet(); return RetryDecision.tryNextHost(cl); } }
@Override public RetryDecision onRequestError(Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { if (nbRetry == m_retryCount) return RetryDecision.rethrow(); else { m_errorRetries.incrementAndGet(); return RetryDecision.tryNextHost(cl); } }
/** * {@inheritDoc} * * <p>This implementation does the following: * * <ul> * <li>if this is the first retry ({@code nbRetry == 0}), it triggers a retry on the next host * in the query plan with the same consistency level ({@link * RetryPolicy.RetryDecision#tryNextHost(ConsistencyLevel) RetryDecision#tryNextHost(null)}. * The rationale is that the first coordinator might have been network-isolated from all * other nodes (thinking they're down), but still able to communicate with the client; in * that case, retrying on the same host has almost no chance of success, but moving to the * next host might solve the issue. * <li>otherwise, the exception is rethrow. * </ul> */ @Override public RetryDecision onUnavailable( Statement statement, ConsistencyLevel cl, int requiredReplica, int aliveReplica, int nbRetry) { return (nbRetry == 0) ? RetryDecision.tryNextHost(null) : RetryDecision.rethrow(); }
@Test(groups = "unit") public void should_expose_decision_properties() throws Throwable { RetryDecision retryAtOne = RetryDecision.retry(ONE); assertThat(retryAtOne.getType()).isEqualTo(RETRY); assertThat(retryAtOne.getRetryConsistencyLevel()).isEqualTo(ONE); assertThat(retryAtOne.isRetryCurrent()).isTrue(); assertThat(retryAtOne.toString()).isEqualTo("Retry at ONE on same host."); RetryDecision tryNextAtOne = RetryDecision.tryNextHost(ONE); assertThat(tryNextAtOne.getType()).isEqualTo(RETRY); assertThat(tryNextAtOne.getRetryConsistencyLevel()).isEqualTo(ONE); assertThat(tryNextAtOne.isRetryCurrent()).isFalse(); assertThat(tryNextAtOne.toString()).isEqualTo("Retry at ONE on next host."); RetryDecision rethrow = RetryDecision.rethrow(); assertThat(rethrow.getType()).isEqualTo(RETHROW); assertThat(rethrow.toString()).isEqualTo("Rethrow"); RetryDecision ignore = RetryDecision.ignore(); assertThat(ignore.getType()).isEqualTo(IGNORE); assertThat(ignore.toString()).isEqualTo("Ignore"); } }
/** * {@inheritDoc} * * <p>For historical reasons, this implementation triggers a retry on the next host in the query * plan with the same consistency level, regardless of the statement's idempotence. Note that this * breaks the general rule stated in {@link RetryPolicy#onRequestError(Statement, * ConsistencyLevel, DriverException, int)}: "a retry should only be attempted if the request is * known to be idempotent".` */ @Override public RetryDecision onRequestError( Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { // do not retry these by default as they generally indicate a data problem or // other issue that is unlikely to be resolved by a retry. if (e instanceof WriteFailureException || e instanceof ReadFailureException) { return RetryDecision.rethrow(); } return RetryDecision.tryNextHost(cl); }
/** * {@inheritDoc} * * <p>This implementation triggers a maximum of one retry. If at least one replica is known to be * alive, the operation is retried at a lower consistency level. */ @Override public RetryDecision onUnavailable( Statement statement, ConsistencyLevel cl, int requiredReplica, int aliveReplica, int nbRetry) { if (nbRetry != 0) return RetryDecision.rethrow(); // JAVA-764: if the requested consistency level is serial, it means that the operation failed at // the paxos phase of a LWT. // Retry on the next host, on the assumption that the initial coordinator could be // network-isolated. if (cl.isSerial()) return RetryDecision.tryNextHost(null); // Tries the biggest CL that is expected to work return maxLikelyToWorkCL(aliveReplica, cl); }
@Test(groups = "short") public void should_log_retried_request_error() throws InterruptedException { simulateError(1, server_error); retryDecision = tryNextHost(LOCAL_ONE); query(); String line = appender.waitAndGet(5000); assertThat(line.trim()) .isEqualTo( expectedMessage( RETRYING_ON_REQUEST_ERROR, "next host", LOCAL_ONE, defaultCL, 0, new ServerError(host1.getSocketAddress(), "Server Error").toString())); }
@Override public RetryDecision onRequestError( Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { return RetryDecision.tryNextHost(cl); }
@Test(groups = "short") public void should_log_retried_write_timeout() throws InterruptedException { simulateError(1, write_request_timeout); retryDecision = tryNextHost(LOCAL_ONE); query(); String line = appender.waitAndGet(5000); assertThat(line.trim()) .isEqualTo( expectedMessage( RETRYING_ON_WRITE_TIMEOUT, "next host", LOCAL_ONE, defaultCL, SIMPLE, 1, 0, 0)); }
@Override public RetryDecision onReadTimeout( Statement statement, ConsistencyLevel cl, int requiredResponses, int receivedResponses, boolean dataRetrieved, int nbRetry) { return RetryDecision.tryNextHost(cl); }
/** {@inheritDoc} */ @Override public RetryDecision onRequestError( Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { // do not retry these by default as they generally indicate a data problem or // other issue that is unlikely to be resolved by a retry. if (e instanceof WriteFailureException || e instanceof ReadFailureException) { return RetryDecision.rethrow(); } return RetryDecision.tryNextHost(cl); }
@Override public RetryDecision onWriteTimeout( Statement statement, ConsistencyLevel cl, WriteType writeType, int requiredAcks, int receivedAcks, int nbRetry) { return RetryDecision.tryNextHost(cl); }
@Test(groups = "short") public void should_log_retried_unavailable() throws InterruptedException { simulateError(1, unavailable); retryDecision = tryNextHost(LOCAL_ONE); query(); String line = appender.waitAndGet(5000); assertThat(line.trim()) .isEqualTo( expectedMessage(RETRYING_ON_UNAVAILABLE, "next host", LOCAL_ONE, defaultCL, 1, 0, 0)); }
@Test(groups = "short") public void should_log_retried_read_timeout() throws InterruptedException { simulateError(1, read_request_timeout); retryDecision = tryNextHost(LOCAL_ONE); query(); String line = appender.waitAndGet(5000); assertThat(line.trim()) .isEqualTo( expectedMessage( RETRYING_ON_READ_TIMEOUT, "next host", LOCAL_ONE, defaultCL, 1, 0, false, 0)); }
@Override public RetryDecision onRequestError( Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { return RetryDecision.tryNextHost(cl); }
@Override public RetryDecision onRequestError( Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { return RetryDecision.tryNextHost(cl); }
@Override public RetryDecision onUnavailable( Statement statement, ConsistencyLevel cl, int requiredReplica, int aliveReplica, int nbRetry) { return RetryDecision.tryNextHost(cl); }
@Override public RetryDecision onWriteTimeout(Statement statement, ConsistencyLevel cl, WriteType writeType, int requiredAcks, int receivedAcks, int nbRetry) { if (nbRetry == m_retryCount) return RetryDecision.rethrow(); else { m_writeRetries.incrementAndGet(); return RetryDecision.tryNextHost(cl); } }
@Override public RetryDecision onRequestError(Statement statement, ConsistencyLevel cl, DriverException e, int nbRetry) { return RetryDecision.tryNextHost(cl); }