Moonlit Moonlit - 4 months ago 21
Java Question

How to simplify retry code block with java 8 features

In my code I have a section which tries to connect to some external interface, if it fails, then it will retry it a fixed number of times. The code works, but is somewhat ugly. I am wondering whether this can be done in a more elegant way using some fancy Java8 features?

int count = 0;
final int maxRetries = 3;
while ( count < maxRetries )
{
try
{
// Some Code
// break out of loop on success
}
catch ( final ExecutionException e )
{
LOG.debug( "retrying..." );
if ( ++count >= maxRetries )
{
LOG.debug( "do something else...");
//do something else
}
}
}

Answer

What you can do is separate out the retry logic. You'll need some ancillary scaffolding:

interface ThrowingTask {
    void run() throws ExecutionException;
}

Now, you write:

boolean runWithRetries(int maxRetries, ThrowingTask t) { 
    int count = 0;
    while (count < maxRetries) {
        try {
            t.run();
            return true;
        }
        catch (ExecutionException e) {
            if (++count >= maxRetries)
                return false;
        }
    }
}

Now, you can run things with retries without having to conflate your task logic with your retry logic:

runWithRetries(MAX_RETRIES, () -> { /* do stuff */ });

You can tweak this as you like to accept lambdas which are called on retry, return the retry count, etc etc. But the game is to write methods like runWithRetries which capture the control flow but abstract over what behavior needs to be done -- so you only have to write your retry loop once, and then fill in the actual behavior you want wherever needed.

Comments