{"id":49815487,"url":"https://github.com/rhuffman/re-retrying","last_synced_at":"2026-05-29T21:00:51.690Z","repository":{"id":57743172,"uuid":"104933093","full_name":"rhuffman/re-retrying","owner":"rhuffman","description":"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.","archived":false,"fork":false,"pushed_at":"2018-07-11T16:23:25.000Z","size":503,"stargazers_count":35,"open_issues_count":4,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-02T00:27:58.484Z","etag":null,"topics":["java","retry"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rhuffman.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-26T20:14:22.000Z","updated_at":"2024-07-30T09:38:07.000Z","dependencies_parsed_at":"2022-09-12T10:11:38.102Z","dependency_job_id":null,"html_url":"https://github.com/rhuffman/re-retrying","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/rhuffman/re-retrying","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhuffman%2Fre-retrying","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhuffman%2Fre-retrying/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhuffman%2Fre-retrying/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhuffman%2Fre-retrying/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhuffman","download_url":"https://codeload.github.com/rhuffman/re-retrying/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhuffman%2Fre-retrying/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33670211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","retry"],"created_at":"2026-05-13T06:00:43.977Z","updated_at":"2026-05-29T21:00:51.684Z","avatar_url":"https://github.com/rhuffman.png","language":"Java","funding_links":[],"categories":["容错组件"],"sub_categories":["微服务框架"],"readme":"\u003c!---\n  Copyright 2012-2015 Ray Holder\n  Modifications copyright 2017-2018 Robert Huffman\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n  \n     http://www.apache.org/licenses/LICENSE-2.0\n  \n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n--\u003e\n\n[![Build Status](https://travis-ci.org/rhuffman/re-retrying.svg?branch=master)](https://travis-ci.org/rhuffman/re-retrying)\n[![Latest Version](http://img.shields.io/badge/latest-3.0.0-brightgreen.svg)](https://github.com/rhuffman/re-retrying/releases/tag/v3.0.0-rc.1)\n[![License](http://img.shields.io/badge/license-apache%202-brightgreen.svg)](https://github.com/rhuffman/re-retrying/blob/master/LICENSE)\n\n## What is this?\nThe 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.\n\nThis 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.\n\nWhy 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.\n\n## Maven\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003etech.huffman.re-retrying\u003c/groupId\u003e\n      \u003cartifactId\u003ere-retrying\u003c/artifactId\u003e\n      \u003cversion\u003e3.0.0\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\n## Gradle\n```groovy\n    compile \"tech.huffman.re-retrying:re-retrying:3.0.0\"\n```\n\n## Quickstart\n\nGiven a function that reads an integer:\n```java\n\npublic int readAnInteger() throws IOException {\n   ...\n}\n```\n\nThe 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`.\n\n```java\n    Retryer retryer = RetryerBuilder.newBuilder()\n        .retryIfResult(Predicates.equalTo(0))\n        .retryIfExceptionOfType(IOException.class)\n        .retryIfRuntimeException()\n        .withStopStrategy(StopStrategies.stopAfterAttempt(3))\n        .build();\n    try {\n      retryer.call(this::readAnInteger);\n    } catch (RetryException | ExecutionException e) {\n      e.printStackTrace();\n    }\n```\n\n## Exponential Backoff\n\nCreate 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.\n\n```java\nRetryer retryer = RetryerBuilder.newBuilder()\n        .retryIfExceptionOfType(IOException.class)\n        .retryIfRuntimeException()\n        .withWaitStrategy(WaitStrategies.exponentialWait(100, 5, TimeUnit.MINUTES))\n        .withStopStrategy(StopStrategies.neverStop())\n        .build();\n```\nYou 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).\n\n## Fibonacci Backoff\n\nCreate 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.\n\n```java\nRetryer retryer = RetryerBuilder.newBuilder()\n        .retryIfExceptionOfType(IOException.class)\n        .retryIfRuntimeException()\n        .withWaitStrategy(WaitStrategies.fibonacciWait(100, 2, TimeUnit.MINUTES))\n        .withStopStrategy(StopStrategies.neverStop())\n        .build();\n```\n\nSimilar to the `ExponentialWaitStrategy`, the `FibonacciWaitStrategy` follows a pattern of waiting an increasing amount of time after each failed attempt.\n\nInstead of an exponential function it's (obviously) using a [Fibonacci sequence](https://en.wikipedia.org/wiki/Fibonacci_numbers) to calculate the wait time.\n\nDepending 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).\n\nThe 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).\n\nInspiration for this implementation came from [Efficient retry/backoff mechanisms](https://paperairoplane.net/?p=640).\n\n## Documentation\nJavadoc can be found [here](http://rholder.github.io/guava-retrying/javadoc/2.0.0).\n\n## Building from source\nThe 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+.\n\n### check out sources\n`git clone git://github.com/rhuffman/re-retrying.git`\n\n### compile and test, build all jars\n`./gradlew build`\n\n### install all jars into your local Maven cache\n`./gradlew install`\n\n## License\nThe re-retrying module is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).\n\n## Contributors\n* Jean-Baptiste Nizet (JB)\n* Jason Dunkelberger (dirkraft)\n* Diwaker Gupta (diwakergupta)\n* Jochen Schalanda (joschi)\n* Shajahan Palayil (shasts)\n* Olivier Grégoire (fror)\n* Andrei Savu (andreisavu)\n* (tchdp)\n* (squalloser)\n* Yaroslav Matveychuk (yaroslavm)\n* Stephan Schroevers (Stephan202)\n* Chad (voiceinsideyou)\n* Kevin Conaway (kevinconaway)\n* Alberto Scotto (alb-i986)\n* Ryan Holder(rholder)\n* Robert Huffman (rhuffman)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhuffman%2Fre-retrying","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhuffman%2Fre-retrying","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhuffman%2Fre-retrying/lists"}