guava-retrying icon indicating copy to clipboard operation
guava-retrying copied to clipboard

[Question] Modify callable in case of a particular exception using RetryListener

Open sudharsannr opened this issue 9 years ago • 0 comments
trafficstars

I have a scenario where I have to run a Database batch (insert/update). Sometimes, I receive "Connection reset" from the database connection. In this case, closing and retrieving a new connection from the pool solved the issue. I wrote a custom retry handler where I did this using try-catch loops and then I wanted to migrate my code to use this utility.

What I have done is that I have filtered using retryifException on a predicate and then added a listener to assign the connection to the callable instance. This is the snippet:

public void batch(String query, Object[][] params) throws ExecutionException, RetryException
{
    if (params == null)
        return;

    RetryCallables.DatabaseBatch callable = new RetryCallables.DatabaseBatch(queryRunner, connection, query,
            params);
    Predicate<Throwable> exceptionPredicate = e -> (e.getMessage()
            .contains(ExceptionMessages.CONNECTION_RESET.toString()) || !(e instanceof SQLException));
    RetryListener listener = new RetryListener() {
        @Override
        public <V> void onRetry(Attempt<V> attempt)
        {
            if (attempt.hasException())
            {
                Throwable cause = attempt.getExceptionCause();
                if (cause != null && cause.getMessage().contains(ExceptionMessages.CONNECTION_RESET.toString()))
                {
                    try
                    {
                        callable.getConnection().close();
                        callable.setConnection(Options.dbPool.getConnection());
                    }
                    catch (SQLException e)
                    {
                        logger.error(e);
                    }
                }
            }
        }
    };

    Retryer<int[]> retryer = RetryerBuilder.<int[]> newBuilder().retryIfException(exceptionPredicate)
            .withRetryListener(listener).withWaitStrategy(WaitStrategies.fixedWait(10, TimeUnit.SECONDS))
            .withStopStrategy(StopStrategies.stopAfterAttempt(Options.NRETRIES)).build();
    retryer.call(callable);
}

But I am not sure whether this would work since the utility does not modify callable. How do I modify the callable in case of a particular exception?

sudharsannr avatar Jun 03 '16 15:06 sudharsannr