Resolves checkstyle errors for patterns starting with letter r (#1072)

* Reduces checkstyle errors in reactor

* Reduces checkstyle errors in reader-writer-lock

* Reduces checkstyle errors in repository

* Reduces checkstyle errors in resource-acquisition-is-initialization

* Reduces checkstyle errors in retry
This commit is contained in:
Anurag Agarwal
2019-11-10 23:12:26 +05:30
committed by Ilkka Seppälä
parent 4dae1fae57
commit 9c8ad4485b
31 changed files with 345 additions and 377 deletions

View File

@ -27,34 +27,35 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The <em>Retry</em> pattern enables applications to handle potentially recoverable failures from
* the environment if the business requirements and nature of the failures allow it. By retrying
* The <em>Retry</em> pattern enables applications to handle potentially recoverable failures from
* the environment if the business requirements and nature of the failures allow it. By retrying
* failed operations on external dependencies, the application may maintain stability and minimize
* negative impact on the user experience.
* <p>
* In our example, we have the {@link BusinessOperation} interface as an abstraction over
* all operations that our application performs involving remote systems. The calling code should
* remain decoupled from implementations.
* <p>
* {@link FindCustomer} is a business operation that looks up a customer's record and returns
* its ID. Imagine its job is performed by looking up the customer in our local database and
* returning its ID. We can pass {@link CustomerNotFoundException} as one of its
* {@link FindCustomer#FindCustomer(java.lang.String, com.iluwatar.retry.BusinessException...)
* constructor parameters} in order to simulate not finding the customer.
* <p>
* Imagine that, lately, this operation has experienced intermittent failures due to some weird
* corruption and/or locking in the data. After retrying a few times the customer is found. The
* database is still, however, expected to always be available. While a definitive solution is
* found to the problem, our engineers advise us to retry the operation a set number
* of times with a set delay between retries, although not too many retries otherwise the end user
* will be left waiting for a long time, while delays that are too short will not allow the database
* to recover from the load.
* <p>
* To keep the calling code as decoupled as possible from this workaround, we have implemented the
* retry mechanism as a {@link BusinessOperation} named {@link Retry}.
*
*
* <p>In our example, we have the {@link BusinessOperation} interface as an abstraction over all
* operations that our application performs involving remote systems. The calling code should remain
* decoupled from implementations.
*
* <p>{@link FindCustomer} is a business operation that looks up a customer's record and returns
* its ID. Imagine its job is performed by looking up the customer in our local database and
* returning its ID. We can pass {@link CustomerNotFoundException} as one of its {@link
* FindCustomer#FindCustomer(java.lang.String, com.iluwatar.retry.BusinessException...) constructor
* parameters} in order to simulate not finding the customer.
*
* <p>Imagine that, lately, this operation has experienced intermittent failures due to some weird
* corruption and/or locking in the data. After retrying a few times the customer is found. The
* database is still, however, expected to always be available. While a definitive solution is
* found to the problem, our engineers advise us to retry the operation a set number of times with a
* set delay between retries, although not too many retries otherwise the end user will be left
* waiting for a long time, while delays that are too short will not allow the database to recover
* from the load.
*
* <p>To keep the calling code as decoupled as possible from this workaround, we have implemented
* the retry mechanism as a {@link BusinessOperation} named {@link Retry}.
*
* @author George Aristy (george.aristy@gmail.com)
* @see <a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/retry">Retry pattern (Microsoft Azure Docs)</a>
* @see <a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/retry">Retry pattern
* (Microsoft Azure Docs)</a>
*/
public final class App {
private static final Logger LOG = LoggerFactory.getLogger(App.class);
@ -62,7 +63,7 @@ public final class App {
/**
* Entry point.
*
*
* @param args not used
* @throws Exception not expected
*/
@ -99,22 +100,22 @@ public final class App {
final String customerId = op.perform();
LOG.info(String.format(
"However, retrying the operation while ignoring a recoverable error will eventually yield "
+ "the result %s after a number of attempts %s", customerId, retry.attempts()
+ "the result %s after a number of attempts %s", customerId, retry.attempts()
));
}
private static void errorWithRetryExponentialBackoff() throws Exception {
final RetryExponentialBackoff<String> retry = new RetryExponentialBackoff<>(
new FindCustomer("123", new CustomerNotFoundException("not found")),
6, //6 attempts
30000, //30 s max delay between attempts
e -> CustomerNotFoundException.class.isAssignableFrom(e.getClass())
);
);
op = retry;
final String customerId = op.perform();
LOG.info(String.format(
"However, retrying the operation while ignoring a recoverable error will eventually yield "
+ "the result %s after a number of attempts %s", customerId, retry.attempts()
));
"However, retrying the operation while ignoring a recoverable error will eventually yield "
+ "the result %s after a number of attempts %s", customerId, retry.attempts()
));
}
}

View File

@ -24,10 +24,10 @@
package com.iluwatar.retry;
/**
* The top-most type in our exception hierarchy that signifies that an unexpected error
* condition occurred. Its use is reserved as a "catch-all" for cases where no other subtype
* captures the specificity of the error condition in question. Calling code is not expected to
* be able to handle this error and should be reported to the maintainers immediately.
* The top-most type in our exception hierarchy that signifies that an unexpected error condition
* occurred. Its use is reserved as a "catch-all" for cases where no other subtype captures the
* specificity of the error condition in question. Calling code is not expected to be able to handle
* this error and should be reported to the maintainers immediately.
*
* @author George Aristy (george.aristy@gmail.com)
*/
@ -35,8 +35,8 @@ public class BusinessException extends Exception {
private static final long serialVersionUID = 6235833142062144336L;
/**
* Ctor
*
* Ctor.
*
* @param message the error message
*/
public BusinessException(String message) {

View File

@ -26,18 +26,18 @@ package com.iluwatar.retry;
/**
* Performs some business operation.
*
* @author George Aristy (george.aristy@gmail.com)
* @param <T> the return type
* @author George Aristy (george.aristy@gmail.com)
*/
@FunctionalInterface
public interface BusinessOperation<T> {
/**
* Performs some business operation, returning a value {@code T} if successful, otherwise throwing
* an exception if an error occurs.
*
*
* @return the return value
* @throws BusinessException if the operation fails. Implementations are allowed to throw more
* specific subtypes depending on the error conditions
* specific subtypes depending on the error conditions
*/
T perform() throws BusinessException;
}

View File

@ -24,10 +24,11 @@
package com.iluwatar.retry;
/**
* Indicates that the customer was not found.
* <p>
* The severity of this error is bounded by its context: was the search for the customer triggered
* by an input from some end user, or were the search parameters pulled from your database?
* Indicates that the customer was not found.
*
* <p>The severity of this error is bounded by its context: was the search for the customer
* triggered by an input from some end user, or were the search parameters pulled from your
* database?
*
* @author George Aristy (george.aristy@gmail.com)
*/
@ -36,7 +37,7 @@ public final class CustomerNotFoundException extends BusinessException {
/**
* Ctor.
*
*
* @param message the error message
*/
public CustomerNotFoundException(String message) {

View File

@ -33,7 +33,7 @@ public final class DatabaseNotAvailableException extends BusinessException {
/**
* Ctor.
*
*
* @param message the error message
*/
public DatabaseNotAvailableException(String message) {

View File

@ -29,9 +29,9 @@ import java.util.List;
/**
* Finds a customer, returning its ID from our records.
* <p>
* This is an imaginary operation that, for some imagined input, returns the ID for a customer.
* However, this is a "flaky" operation that is supposed to fail intermittently, but for the
*
* <p>This is an imaginary operation that, for some imagined input, returns the ID for a customer.
* However, this is a "flaky" operation that is supposed to fail intermittently, but for the
* purposes of this example it fails in a programmed way depending on the constructor parameters.
*
* @author George Aristy (george.aristy@gmail.com)
@ -42,15 +42,15 @@ public final class FindCustomer implements BusinessOperation<String> {
/**
* Ctor.
*
*
* @param customerId the final result of the remote operation
* @param errors the errors to throw before returning {@code customerId}
* @param errors the errors to throw before returning {@code customerId}
*/
public FindCustomer(String customerId, BusinessException... errors) {
this.customerId = customerId;
this.errors = new ArrayDeque<>(List.of(errors));
}
@Override
public String perform() throws BusinessException {
if (!this.errors.isEmpty()) {

View File

@ -33,8 +33,8 @@ import java.util.function.Predicate;
/**
* Decorates {@link BusinessOperation business operation} with "retry" capabilities.
*
* @author George Aristy (george.aristy@gmail.com)
* @param <T> the remote op's return type
* @author George Aristy (george.aristy@gmail.com)
*/
public final class Retry<T> implements BusinessOperation<T> {
private final BusinessOperation<T> op;
@ -46,18 +46,18 @@ public final class Retry<T> implements BusinessOperation<T> {
/**
* Ctor.
*
* @param op the {@link BusinessOperation} to retry
*
* @param op the {@link BusinessOperation} to retry
* @param maxAttempts number of times to retry
* @param delay delay (in milliseconds) between attempts
* @param delay delay (in milliseconds) between attempts
* @param ignoreTests tests to check whether the remote exception can be ignored. No exceptions
* will be ignored if no tests are given
* will be ignored if no tests are given
*/
@SafeVarargs
public Retry(
BusinessOperation<T> op,
int maxAttempts,
long delay,
BusinessOperation<T> op,
int maxAttempts,
long delay,
Predicate<Exception>... ignoreTests
) {
this.op = op;
@ -70,7 +70,7 @@ public final class Retry<T> implements BusinessOperation<T> {
/**
* The errors encountered while retrying, in the encounter order.
*
*
* @return the errors encountered while retrying
*/
public List<Exception> errors() {
@ -79,7 +79,7 @@ public final class Retry<T> implements BusinessOperation<T> {
/**
* The number of retries performed.
*
*
* @return the number of retries performed
*/
public int attempts() {
@ -93,7 +93,7 @@ public final class Retry<T> implements BusinessOperation<T> {
return this.op.perform();
} catch (BusinessException e) {
this.errors.add(e);
if (this.attempts.incrementAndGet() >= this.maxAttempts || !this.test.test(e)) {
throw e;
}
@ -104,7 +104,6 @@ public final class Retry<T> implements BusinessOperation<T> {
//ignore
}
}
}
while (true);
} while (true);
}
}

View File

@ -34,8 +34,8 @@ import java.util.function.Predicate;
/**
* Decorates {@link BusinessOperation business operation} with "retry" capabilities.
*
* @author George Aristy (george.aristy@gmail.com)
* @param <T> the remote op's return type
* @author George Aristy (george.aristy@gmail.com)
*/
public final class RetryExponentialBackoff<T> implements BusinessOperation<T> {
private static final Random RANDOM = new Random();
@ -46,20 +46,20 @@ public final class RetryExponentialBackoff<T> implements BusinessOperation<T> {
private final Predicate<Exception> test;
private final List<Exception> errors;
/**
* Ctor.
*
* @param op the {@link BusinessOperation} to retry
* @param maxAttempts number of times to retry
* @param ignoreTests tests to check whether the remote exception can be ignored. No exceptions
* will be ignored if no tests are given
*/
/**
* Ctor.
*
* @param op the {@link BusinessOperation} to retry
* @param maxAttempts number of times to retry
* @param ignoreTests tests to check whether the remote exception can be ignored. No exceptions
* will be ignored if no tests are given
*/
@SafeVarargs
public RetryExponentialBackoff(
BusinessOperation<T> op,
int maxAttempts,
long maxDelay,
Predicate<Exception>... ignoreTests
BusinessOperation<T> op,
int maxAttempts,
long maxDelay,
Predicate<Exception>... ignoreTests
) {
this.op = op;
this.maxAttempts = maxAttempts;
@ -69,20 +69,20 @@ public final class RetryExponentialBackoff<T> implements BusinessOperation<T> {
this.errors = new ArrayList<>();
}
/**
* The errors encountered while retrying, in the encounter order.
*
* @return the errors encountered while retrying
*/
/**
* The errors encountered while retrying, in the encounter order.
*
* @return the errors encountered while retrying
*/
public List<Exception> errors() {
return Collections.unmodifiableList(this.errors);
}
/**
* The number of retries performed.
*
* @return the number of retries performed
*/
/**
* The number of retries performed.
*
* @return the number of retries performed
*/
public int attempts() {
return this.attempts.intValue();
}
@ -107,8 +107,7 @@ public final class RetryExponentialBackoff<T> implements BusinessOperation<T> {
//ignore
}
}
}
while (true);
} while (true);
}
}