项目作者: EnigmaBridge

项目描述 :
Simple retry logic for sync/async operations (fast retry, back-off)
高级语言: Java
项目地址: git://github.com/EnigmaBridge/retry.java.git
创建时间: 2016-08-15T13:36:47Z
项目社区:https://github.com/EnigmaBridge/retry.java

开源协议:MIT License

下载


Retry mechanism

Build Status

Very simple retry mechanism with small dependency footprint. Visit http://enigmabridge.github.io/retry.java for Javadoc documentation.

Maven repository

  1. <dependency>
  2. <groupId>com.enigmabridge</groupId>
  3. <artifactId>retry</artifactId>
  4. <version>0.1.0</version>
  5. </dependency>

Gradle

  1. compile 'com.enigmabridge:retry:0.1.0'

Contributing

Pull requests and bug reports are welcome

Examples

Synchronous Backoff

  1. // Initialize retry strategy to Backoff
  2. final EBRetryStrategy retryStrategy = new EBRetryStrategyBackoff.Builder()
  3. .setMaxElapsedTimeMillis(1000*60*5) // Limit on total time
  4. .build();
  5. // New retry mechanism instance, for each job.
  6. final EBRetry<ResultObject, Throwable> ebRetry = new EBRetry<ResultObject, Throwable>(retryStrategy.copy());
  7. // Define retry job
  8. ebRetry.setJob(new EBRetryJobSimpleSafeThrErr<ResultObject>() {
  9. @Override
  10. public void runAsyncNoException(EBCallback<ResultObject, Throwable> callback) throws Throwable {
  11. try {
  12. // Do the actuall job here. May be called multiple times.
  13. final ResultObject result = our_task_to_retry();
  14. // Signalize success to the retry object so it knows we can quit trying.
  15. callback.onSuccess(result);
  16. } catch(IOException exception) {
  17. // You mau log it if you want
  18. //LOG.debug("Job failed");
  19. // Call fail callback so retry mechanism knows this attempt was
  20. // not successful and it should continue trying or give up
  21. // if number of attempts or total ellapsed time exceeded threshold.
  22. //
  23. // Fail accepts job error object. We usually use Throwable as an job error
  24. // as it usually corresponds with the failure (e.g., IOException on network error).
  25. // We wrap throwable to the job error and pass it to the fail callback.
  26. callback.onFail(new EBRetryJobErrorThr(exception), false);
  27. }
  28. }
  29. });
  30. // Start the job synchronously.
  31. try {
  32. return ebRetry.runSync();
  33. } catch (EBRetryFailedException e) {
  34. throw new IOException(e);
  35. } catch (EBRetryException e){
  36. throw new IOException("Fatal request error", e);
  37. }

Asynchronous backoff

Retry mechanism supports asynchronous jobs.

  1. // Initialize retry strategy to Backoff
  2. final EBRetryStrategy retryStrategy = new EBRetryStrategyBackoff.Builder()
  3. .setMaxElapsedTimeMillis(1000*60*5) // Limit on total time
  4. .build();
  5. // New retry mechanism instance, for each job.
  6. final EBRetry<ResultObject, Throwable> ebRetry = new EBRetry<ResultObject, Throwable>(retryStrategy.copy());
  7. // Define retry job
  8. ebRetry.setJob(new EBRetryJobSimpleSafeThrErr<ResultObject>() {
  9. @Override
  10. public void runAsyncNoException(EBCallback<ResultObject, Throwable> callback) throws Throwable {
  11. try {
  12. // Do the actuall job here. May be called multiple times.
  13. final ResultObject result = our_task_to_retry();
  14. // Signalize success to the retry object so it knows we can quit trying.
  15. callback.onSuccess(result);
  16. } catch(IOException exception) {
  17. callback.onFail(new EBRetryJobErrorThr(exception), false);
  18. }
  19. }
  20. });
  21. // Define async listener. Will be called on success / fail.
  22. // Fail = backoff strategy expired (threshold exceeded)
  23. ebRetry.addListener(new EBRetryListener<EBRawResponse, Throwable>() {
  24. @Override
  25. public void onSuccess(EBRawResponse ebRawResponse, EBRetry<EBRawResponse, Throwable> retry) {
  26. // hooray, success
  27. }
  28. @Override
  29. public void onFail(EBRetryJobError<Throwable> error, EBRetry<EBRawResponse, Throwable> retry) {
  30. // well, we tried
  31. }
  32. });
  33. // Run asynchronously.
  34. // Keep future if you want to detect if job is still running
  35. // Or to cancel it or to skip current backoff waiting interval (runNow())
  36. final EBFuture<EBRawResponse, Throwable> future = ebRetry.runAsync();

Options to build EBRetryStrategyBackoff.Builder - quick reference

  • setMaxAttempts(int tries) - how many times will be the EBRetryJob executed;
  • setMaxIntervalMillis(int milliseconds) - maximum time for the job to be run - it will be interrupted when the time limit is reached;
  • setMaxElapsedTimeMillis(int milliseconds) - the maximum value of a counter, when reached, nextBackoffMillis() will start returning BackOff.STOP;
  • setMultiplier(int multiplier) - value to multiply the current interval with for each retry attempt;
  • setRandomizationFactor(double randomizationFactor) - a factor of 0.5 results in a random period ranging between 50% below and 50% above the retry interval;
  • setJSON(org.json.JSONObject object) - reads settings from JSON;
  • setInitialIntervalLimit(int initialIntervalLimit) - initial retry interval in milliseconds.