Skip to content

Instantly share code, notes, and snippets.

@evan-burke
Forked from orottier/RetryTest.php
Last active September 14, 2018 04:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evan-burke/533c687fdccce00077208ec50ef461c6 to your computer and use it in GitHub Desktop.
Save evan-burke/533c687fdccce00077208ec50ef461c6 to your computer and use it in GitHub Desktop.
Retry function for PHP with linear backoff
<?php
/*
* Retry function for e.g. external API calls
*
* Will try the risky API call, and retries with an ever increasing delay if it fails
* Throws the latest error if $maxRetries is reached,
* otherwise it will return the value returned from the closure.
*
*/
function retry(callable $callable, $args = NULL, $maxRetries = 20, $initialWait = 1.0, $additionalWait = 1)
{
try {
return call_user_func($callable, $args);
} catch (Exception $e) {
// get whole inheritance chain
$errors = class_parents($e);
array_push($errors, get_class($e));
// linearly increasing backoff
if ($maxRetries > 0) {
usleep($initialWait * 1E6);
return retry($callable, $args, $maxRetries - 1, $initialWait + $additionalWait);
}
// max retries reached
throw $e;
}
}
<?php
# var used to keep track of attempts, just for this example, so we can fail a few times before succeeding.
# The retry function tracks attempts on its own.
$iter = 0;
function failtwice($input) {
global $iter;
$iter++;
print("function failtwice called. input: " . $input . "\n");
if ($iter <= 2) {
throw new Exception('Fail twice exception. input: ' . $input);
}
return $iter;
}
$input_global = 'abcdef';
# normal, where it succeeds after a retry
$val = retry('failtwice', $input_global);
print("return value: " . $val . "\n");
# reset
$iter = 0;
print("this one should generate an exception")
# where it fails out after exceeding $maxRetries
$val2 = retry('failtwice', $input_global, $maxRetries = 1);
print("done\n");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment