-
-
Save evan-burke/533c687fdccce00077208ec50ef461c6 to your computer and use it in GitHub Desktop.
Retry function for PHP with linear backoff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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