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.