https://github.com/rhuffman/re-retrying
A Java library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that communicates with a remote service with flaky uptime.
https://github.com/rhuffman/re-retrying
java retry
Last synced: 26 days ago
JSON representation
A Java library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that communicates with a remote service with flaky uptime.
- Host: GitHub
- URL: https://github.com/rhuffman/re-retrying
- Owner: rhuffman
- License: apache-2.0
- Created: 2017-09-26T20:14:22.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-07-11T16:23:25.000Z (almost 8 years ago)
- Last Synced: 2024-11-02T00:27:58.484Z (over 1 year ago)
- Topics: java, retry
- Language: Java
- Homepage:
- Size: 491 KB
- Stars: 35
- Watchers: 6
- Forks: 6
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: HISTORY.md
- License: LICENSE
Awesome Lists containing this project
- awesome-java - ReRetrying
README
[](https://travis-ci.org/rhuffman/re-retrying)
[](https://github.com/rhuffman/re-retrying/releases/tag/v3.0.0-rc.1)
[](https://github.com/rhuffman/re-retrying/blob/master/LICENSE)
## What is this?
The re-retrying module provides a general purpose method for retrying arbitrary Java code with specific stop, retry, and exception handling capabilities that are enhanced by Guava's predicate matching.
This is a fork of the [guava-retrying](https://github.com/rholder/guava-retrying) library by Ryan Holder (rholder), which is itself a fork of the [RetryerBuilder](http://code.google.com/p/guava-libraries/issues/detail?id=490) by Jean-Baptiste Nizet (JB). The guava-retrying project added a Gradle build for pushing it up to Maven Central, and exponential and Fibonacci backoff [WaitStrategies](http://rholder.github.io/guava-retrying/javadoc/2.0.0/com/github/rholder/retry/WaitStrategies.html) that might be useful for situations where more well-behaved service polling is preferred.
Why was this fork necessary? The primary reason was to make it compatible with projects using later versions of Guava. See [this project's Wiki](https://github.com/rhuffman/re-retrying/wiki#why-fork) for more details.
## Maven
```xml
tech.huffman.re-retrying
re-retrying
3.0.0
```
## Gradle
```groovy
compile "tech.huffman.re-retrying:re-retrying:3.0.0"
```
## Quickstart
Given a function that reads an integer:
```java
public int readAnInteger() throws IOException {
...
}
```
The following will retry if the result of the method is zero, if an `IOException` is thrown, or if any other `RuntimeException` is thrown from the `call()` method. It will stop after attempting to retry 3 times and throw a `RetryException` that contains information about the last failed attempt. If any other `Exception` pops out of the `call()` method it's wrapped and rethrown in an `ExecutionException`.
```java
Retryer retryer = RetryerBuilder.newBuilder()
.retryIfResult(Predicates.equalTo(0))
.retryIfExceptionOfType(IOException.class)
.retryIfRuntimeException()
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.build();
try {
retryer.call(this::readAnInteger);
} catch (RetryException | ExecutionException e) {
e.printStackTrace();
}
```
## Exponential Backoff
Create a `Retryer` that retries forever, waiting after every failed retry in increasing exponential backoff intervals until at most 5 minutes. After 5 minutes, retry from then on in 5 minute intervals.
```java
Retryer retryer = RetryerBuilder.newBuilder()
.retryIfExceptionOfType(IOException.class)
.retryIfRuntimeException()
.withWaitStrategy(WaitStrategies.exponentialWait(100, 5, TimeUnit.MINUTES))
.withStopStrategy(StopStrategies.neverStop())
.build();
```
You can read more about [exponential backoff](http://en.wikipedia.org/wiki/Exponential_backoff) and the historic role it played in the development of TCP/IP in [Congestion Avoidance and Control](http://ee.lbl.gov/papers/congavoid.pdf).
## Fibonacci Backoff
Create a `Retryer` that retries forever, waiting after every failed retry in increasing Fibonacci backoff intervals until at most 2 minutes. After 2 minutes, retry from then on in 2 minute intervals.
```java
Retryer retryer = RetryerBuilder.newBuilder()
.retryIfExceptionOfType(IOException.class)
.retryIfRuntimeException()
.withWaitStrategy(WaitStrategies.fibonacciWait(100, 2, TimeUnit.MINUTES))
.withStopStrategy(StopStrategies.neverStop())
.build();
```
Similar to the `ExponentialWaitStrategy`, the `FibonacciWaitStrategy` follows a pattern of waiting an increasing amount of time after each failed attempt.
Instead of an exponential function it's (obviously) using a [Fibonacci sequence](https://en.wikipedia.org/wiki/Fibonacci_numbers) to calculate the wait time.
Depending on the problem at hand, the `FibonacciWaitStrategy` might perform better and lead to better throughput than the `ExponentialWaitStrategy` - at least according to [A Performance Comparison of Different Backoff Algorithms under Different Rebroadcast Probabilities for MANETs](http://www.comp.leeds.ac.uk/ukpew09/papers/12.pdf).
The implementation of `FibonacciWaitStrategy` is using an iterative version of the Fibonacci because a (naive) recursive version will lead to a [StackOverflowError](http://docs.oracle.com/javase/7/docs/api/java/lang/StackOverflowError.html) at a certain point (although very unlikely with useful parameters for retrying).
Inspiration for this implementation came from [Efficient retry/backoff mechanisms](https://paperairoplane.net/?p=640).
## Documentation
Javadoc can be found [here](http://rholder.github.io/guava-retrying/javadoc/2.0.0).
## Building from source
The re-retrying module uses a [Gradle](http://gradle.org)-based build system. In the instructions below, [`./gradlew`](http://vimeo.com/34436402) is invoked from the root of the source tree and serves as a cross-platform, self-contained bootstrap mechanism for the build. The only prerequisites are [Git](https://help.github.com/articles/set-up-git) and JDK 1.8+.
### check out sources
`git clone git://github.com/rhuffman/re-retrying.git`
### compile and test, build all jars
`./gradlew build`
### install all jars into your local Maven cache
`./gradlew install`
## License
The re-retrying module is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).
## Contributors
* Jean-Baptiste Nizet (JB)
* Jason Dunkelberger (dirkraft)
* Diwaker Gupta (diwakergupta)
* Jochen Schalanda (joschi)
* Shajahan Palayil (shasts)
* Olivier Grégoire (fror)
* Andrei Savu (andreisavu)
* (tchdp)
* (squalloser)
* Yaroslav Matveychuk (yaroslavm)
* Stephan Schroevers (Stephan202)
* Chad (voiceinsideyou)
* Kevin Conaway (kevinconaway)
* Alberto Scotto (alb-i986)
* Ryan Holder(rholder)
* Robert Huffman (rhuffman)