{"id":13565418,"url":"https://github.com/rholder/guava-retrying","last_synced_at":"2025-05-14T13:10:09.045Z","repository":{"id":4426885,"uuid":"5564847","full_name":"rholder/guava-retrying","owner":"rholder","description":"This is a small extension to Google's Guava library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that talks to a remote service with flaky uptime.","archived":false,"fork":false,"pushed_at":"2023-03-28T11:48:46.000Z","size":612,"stargazers_count":1453,"open_issues_count":64,"forks_count":276,"subscribers_count":66,"default_branch":"master","last_synced_at":"2025-04-11T06:12:56.299Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/rholder.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,"governance":null}},"created_at":"2012-08-27T00:12:18.000Z","updated_at":"2025-04-09T09:34:04.000Z","dependencies_parsed_at":"2023-07-05T19:33:05.900Z","dependency_job_id":null,"html_url":"https://github.com/rholder/guava-retrying","commit_stats":{"total_commits":89,"total_committers":11,"mean_commits":8.090909090909092,"dds":0.2584269662921348,"last_synced_commit":"177b6c9b9f3e7957f404f0bdb8e23374cb1de43f"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rholder%2Fguava-retrying","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rholder%2Fguava-retrying/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rholder%2Fguava-retrying/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rholder%2Fguava-retrying/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rholder","download_url":"https://codeload.github.com/rholder/guava-retrying/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254149977,"owners_count":22022852,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-01T13:01:46.627Z","updated_at":"2025-05-14T13:10:04.024Z","avatar_url":"https://github.com/rholder.png","language":"Java","funding_links":[],"categories":["Java","容错组件"],"sub_categories":[],"readme":"[![Build Status](http://img.shields.io/travis/rholder/guava-retrying.svg)](https://travis-ci.org/rholder/guava-retrying) [![Latest Version](http://img.shields.io/badge/latest-2.0.0-brightgreen.svg)](https://github.com/rholder/guava-retrying/releases/tag/v2.0.0) [![License](http://img.shields.io/badge/license-apache%202-brightgreen.svg)](https://github.com/rholder/guava-retrying/blob/master/LICENSE)\n\n\n##What is this?\nThe guava-retrying module provides a general purpose method for retrying arbitrary Java code with specific stop, retry,\nand exception handling capabilities that are enhanced by Guava's predicate matching.\n\nThis is a fork of the excellent RetryerBuilder code posted [here](http://code.google.com/p/guava-libraries/issues/detail?id=490)\nby Jean-Baptiste Nizet (JB).  I've added a Gradle build for pushing it up to my little corner of Maven Central so that\nothers can easily pull it into their existing projects with minimal effort.  It also includes\nexponential and Fibonacci backoff [WaitStrategies](http://rholder.github.io/guava-retrying/javadoc/2.0.0/com/github/rholder/retry/WaitStrategies.html)\nthat might be useful for situations where more well-behaved service polling is preferred.\n\n##Maven\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.github.rholder\u003c/groupId\u003e\n      \u003cartifactId\u003eguava-retrying\u003c/artifactId\u003e\n      \u003cversion\u003e2.0.0\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\n##Gradle\n```groovy\n    compile \"com.github.rholder:guava-retrying:2.0.0\"\n```\n\n##Quickstart\nA minimal sample of some of the functionality would look like:\n\n```java\nCallable\u003cBoolean\u003e callable = new Callable\u003cBoolean\u003e() {\n    public Boolean call() throws Exception {\n        return true; // do something useful here\n    }\n};\n\nRetryer\u003cBoolean\u003e retryer = RetryerBuilder.\u003cBoolean\u003enewBuilder()\n        .retryIfResult(Predicates.\u003cBoolean\u003eisNull())\n        .retryIfExceptionOfType(IOException.class)\n        .retryIfRuntimeException()\n        .withStopStrategy(StopStrategies.stopAfterAttempt(3))\n        .build();\ntry {\n    retryer.call(callable);\n} catch (RetryException e) {\n    e.printStackTrace();\n} catch (ExecutionException e) {\n    e.printStackTrace();\n}\n```\n\nThis will retry whenever the result of the `Callable` is null, if an `IOException` is thrown, or if any other\n`RuntimeException` is thrown from the `call()` method. It will stop after attempting to retry 3 times and throw a\n`RetryException` that contains information about the last failed attempt. If any other `Exception` pops out of the\n`call()` method it's wrapped and rethrown in an `ExecutionException`.\n\n##Exponential Backoff\n\nCreate a `Retryer` that retries forever, waiting after every failed retry in increasing exponential backoff intervals\nuntil at most 5 minutes. After 5 minutes, retry from then on in 5 minute intervals.\n\n```java\nRetryer\u003cBoolean\u003e retryer = RetryerBuilder.\u003cBoolean\u003enewBuilder()\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\nit 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\nuntil at most 2 minutes. After 2 minutes, retry from then on in 2 minute intervals.\n\n```java\nRetryer\u003cBoolean\u003e retryer = RetryerBuilder.\u003cBoolean\u003enewBuilder()\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\nof time after each failed attempt.\n\nInstead of an exponential function it's (obviously) using a\n[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\nthe `ExponentialWaitStrategy` - at least according to\n[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\nversion will lead to a [StackOverflowError](http://docs.oracle.com/javase/7/docs/api/java/lang/StackOverflowError.html)\nat 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 guava-retrying module uses a [Gradle](http://gradle.org)-based build system. In the instructions\nbelow, [`./gradlew`](http://vimeo.com/34436402) is invoked from the root of the source tree and serves as\na cross-platform, self-contained bootstrap mechanism for the build. The only\nprerequisites are [Git](https://help.github.com/articles/set-up-git) and JDK 1.6+.\n\n### check out sources\n`git clone git://github.com/rholder/guava-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 guava-retrying module is released under version 2.0 of the\n[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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frholder%2Fguava-retrying","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frholder%2Fguava-retrying","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frholder%2Fguava-retrying/lists"}