private <K extends Exception> void handleBackoff(RetryableCassandraRequest<?, K> req, InetSocketAddress hostTried, Exception ex, RequestExceptionHandlerStrategy strategy) { if (!shouldBackoff(ex, strategy)) { return; } long backOffPeriod = strategy.getBackoffPeriod(req.getNumberOfAttemptsOnHost(hostTried)); log.info("Retrying a query, {}, with backoff of {}ms, intended for host {}.", UnsafeArg.of("queryString", req.getFunction().toString()), SafeArg.of("sleepDuration", backOffPeriod), SafeArg.of("hostName", CassandraLogHelper.host(hostTried))); try { Thread.sleep(backOffPeriod); } catch (InterruptedException i) { Thread.currentThread().interrupt(); throw new RuntimeException(i); } }
@Test public void connectionExceptionsShouldBackoffDefault() { for (Exception ex : CONNECTION_EXCEPTIONS) { assertTrue(String.format("Exception %s should backoff", ex), handlerLegacy.shouldBackoff(ex, handlerLegacy.getStrategy())); } }
@Test public void cassandraLoadExceptionsShouldBackoffConservative() { for (Exception ex : INDICATIVE_OF_CASSANDRA_LOAD_EXCEPTIONS) { assertTrue(String.format("Exception %s should backoff", ex), handlerConservative.shouldBackoff(ex, handlerConservative.getStrategy())); } }
@Test public void connectionExceptionsShouldBackoffConservative() { for (Exception ex : CONNECTION_EXCEPTIONS) { assertTrue(String.format("Exception %s should backoff", ex), handlerConservative.shouldBackoff(ex, handlerConservative.getStrategy())); } }
@Test public void fastFailoverExceptionsShouldNotBackoffDefault() { for (Exception ex : FAST_FAILOVER_EXCEPTIONS) { assertFalse(String.format("Exception %s should not backoff", ex), handlerLegacy.shouldBackoff(ex, handlerLegacy.getStrategy())); } }
@Test public void fastFailoverExceptionsShouldNotBackoffConservative() { for (Exception ex : FAST_FAILOVER_EXCEPTIONS) { assertFalse(String.format("Exception %s should not backoff", ex), handlerConservative.shouldBackoff(ex, handlerConservative.getStrategy())); } }
@Test public void cassandraLoadExceptionsShouldBackoffDefault() { for (Exception ex : INDICATIVE_OF_CASSANDRA_LOAD_EXCEPTIONS) { assertTrue(String.format("Exception %s should backoff", ex), handlerLegacy.shouldBackoff(ex, handlerLegacy.getStrategy())); } }
@Test public void transientExceptionsShouldNotBackoffDefault() { for (Exception ex : TRANSIENT_EXCEPTIONS) { assertFalse(handlerLegacy.shouldBackoff(ex, handlerLegacy.getStrategy())); } }
@Test public void transientExceptionsShouldBackoffConservative() { for (Exception ex : TRANSIENT_EXCEPTIONS) { assertTrue(handlerConservative.shouldBackoff(ex, handlerConservative.getStrategy())); } }
@Test public void changingHandlerModeHasNoEffectWithoutGetStrategy() { Exception ex = Iterables.get(TRANSIENT_EXCEPTIONS, 0); CassandraRequestExceptionHandler handler = new CassandraRequestExceptionHandler( () -> MAX_RETRIES_PER_HOST, () -> MAX_RETRIES_TOTAL, this::mutableMode, new Blacklist(config)); CassandraRequestExceptionHandler.RequestExceptionHandlerStrategy conservativeStrategy = handler.getStrategy(); assertTrue(handler.shouldBackoff(ex, handler.getStrategy())); flipMode(); assertTrue(handler.shouldBackoff(ex, conservativeStrategy)); assertFalse(handler.shouldBackoff(ex, handler.getStrategy())); }
private <K extends Exception> void handleBackoff(RetryableCassandraRequest<?, K> req, InetSocketAddress hostTried, Exception ex, RequestExceptionHandlerStrategy strategy) { if (!shouldBackoff(ex, strategy)) { return; } long backOffPeriod = strategy.getBackoffPeriod(req.getNumberOfAttemptsOnHost(hostTried)); log.info("Retrying a query, {}, with backoff of {}ms, intended for host {}.", UnsafeArg.of("queryString", req.getFunction().toString()), SafeArg.of("sleepDuration", backOffPeriod), SafeArg.of("hostName", CassandraLogHelper.host(hostTried))); try { Thread.sleep(backOffPeriod); } catch (InterruptedException i) { Thread.currentThread().interrupt(); throw new RuntimeException(i); } }