In: Computer Science
Java does not have a retry keyword like Ruby. How can we implement the same sort of functionality?
I wanted to be able to write this retry logic and error handling code in one place and use it for a number of different method calls. There are several ways to do this, but previously in Java 7 I would have just written an abstract class with a single abstract method such as:
public abstract class RetryCommand<T> {
private int maxRetries;
public RetryCommand(int maxRetries) {
this.maxRetries = maxRetries;
}
// This abstract command is the method that will be implemented
public abstract T command();
public final T run() throws RuntimeException {
try {
return command();
} catch (Exception e) {
return retry();
}
}
private final T retry() throws RuntimeException {
System.out.println("FAILED - Command failed, will be retried " + maxRetries + " times.");
int retryCounter = 0;
while (retryCounter < maxRetries) {
try {
return command();
} catch (Exception e) {
retryCounter++;
System.out.println("FAILED - Command failed on retry " + retryCounter + " of " + maxRetries + " error: " + ex );
if (retryCounter >= maxRetries) {
System.out.println("Max retries exceeded.");
break;
}
}
}
throw new RuntimeException("Command failed on all of " + maxRetries + " retries");
}
}
Then in my Gateway code, for each method that I want to wrap with my retry logic I would just do the following:
public class MyGateway {
private RetryCommand<String> retryCommand;
public MyGateway(int maxRetries) {
retryCommand = new RetryCommand<>(maxRetries);
}
// Inline create an instance of the abstract class RetryCommand
// Define the body of the "command" method
// Execute the "run" method and return the result
public String getThing(final String id) {
return new RetryCommand<String>() {
public String command() {
return client.getThatThing(id);
}
}.run();
}
}
The reason for this layout was I could not pass a function as a parameter to a method, like I have done in Scala, Python, and C#. However, now that we have Java 8, we can finally pass functions as parameters using the handy features in java.util.function package!
I hope you got your answer.