PHPackages                             tagadvance/elephant-retrying - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. tagadvance/elephant-retrying

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tagadvance/elephant-retrying
============================

This is a port of the guava-retrying module 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.

1.0.0(6y ago)02Apache-2.0PHPPHP ^7.4.0

Since Feb 22Pushed 6y agoCompare

[ Source](https://github.com/tagadvance/elephant-retrying)[ Packagist](https://packagist.org/packages/tagadvance/elephant-retrying)[ RSS](/packages/tagadvance-elephant-retrying/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

[![Build Status](https://camo.githubusercontent.com/c5354d0fa335d4382206db7926742ac4e68a3682655f6f86dccddf81c4200062/68747470733a2f2f7472617669732d63692e6f72672f746167616476616e63652f656c657068616e742d7265747279696e672e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/tagadvance/elephant-retrying)[![Coverage Status](https://camo.githubusercontent.com/b7a937452376252786dfb672cae19d65bbeb0dac69b3da48ee97b6b08f579f39/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f746167616476616e63652f656c657068616e742d7265747279696e672f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/tagadvance/elephant-retrying?branch=master)[![License](https://camo.githubusercontent.com/957e02aff8ec4e4974af8e16537860040f5c957cb03e4d394819dacf95130672/687474703a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d617061636865253230322d627269676874677265656e2e737667)](https://github.com/tagadvance/elephant-retrying/blob/master/LICENSE)

What is this?
-------------

[](#what-is-this)

The elephant-retrying module provides a general purpose method for retrying arbitrary PHP code with specific stop, retry, and exception handling capabilities.

This is a fork of the excellent guava-retrying code posted [here](https://github.com/rholder/guava-retrying) by Ray Holder (rholder).

Port Accommodations
-------------------

[](#port-accommodations)

- Generics have been removed because PHP does not support generics.
- All time units have been converted to seconds of type `float`.
- Time limiter has been removed as such functionality would be difficult to implement in PHP.

Composer
--------

[](#composer)

```
composer require tagadvance/elephant-retrying
```

Quickstart
----------

[](#quickstart)

A minimal sample of some of the functionality would look like:

```
$retryer = RetryerBuilder::newBuilder()
	->retryIfResult('is_null')
	->retryIfExceptionOfType(\RuntimeException::class)
	->withStopStrategy(StopStrategies . stopAfterAttempt(3))
	->build();
try {
	$retryer->call(fn() => true); // do something useful here
} catch (RetryException $e) {
	print $e->getTraceAsString();
} catch (ExecutionException $e) {
	print $e->getTraceAsString();
}
```

This will retry whenever the result of the `Callable` is null, 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`.

Exponential Backoff
-------------------

[](#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.

```
$maximumWaitTimeSeconds = 300; // 5 minutes
$retryer = RetryerBuilder::newBuilder()
        ->retryIfExceptionOfType(\RuntimeException::class)
        ->withWaitStrategy(WaitStrategies::exponentialWait(1, $maximumWaitTimeSeconds))
        ->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
-----------------

[](#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.

```
$maximumWaitTimeSeconds = 120; // 2 minutes
$retryer = RetryerBuilder::newBuilder()
	->retryIfExceptionOfType(\RuntimeException::class)
	->withWaitStrategy(WaitStrategies::fibonacciWait(1, $maximumWaitTimeSeconds))
	->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).

### Source

[](#source)

`git clone git@github.com:tagadvance/elephant-retrying.git`

### Clean, Install, and Test

[](#clean-install-and-test)

`./make`

License
-------

[](#license)

The guava-retrying module is released under version 2.0 of the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity2

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

2269d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b280291fbbbe53d05587495c671005c222547d33f3a9cd198287a39b21c9cc32?d=identicon)[tagadvance](/maintainers/tagadvance)

---

Top Contributors

[![rholder](https://avatars.githubusercontent.com/u/734150?v=4)](https://github.com/rholder "rholder (83 commits)")[![joschi](https://avatars.githubusercontent.com/u/43951?v=4)](https://github.com/joschi "joschi (7 commits)")[![shasts](https://avatars.githubusercontent.com/u/1254523?v=4)](https://github.com/shasts "shasts (6 commits)")[![dirkraft](https://avatars.githubusercontent.com/u/487920?v=4)](https://github.com/dirkraft "dirkraft (1 commits)")[![Stephan202](https://avatars.githubusercontent.com/u/513280?v=4)](https://github.com/Stephan202 "Stephan202 (1 commits)")[![yaroslavm](https://avatars.githubusercontent.com/u/986207?v=4)](https://github.com/yaroslavm "yaroslavm (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tagadvance-elephant-retrying/health.svg)

```
[![Health](https://phpackages.com/badges/tagadvance-elephant-retrying/health.svg)](https://phpackages.com/packages/tagadvance-elephant-retrying)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
