Last active
December 20, 2015 06:58
-
-
Save kvz/6089432 to your computer and use it in GitHub Desktop.
Tries your function several times with a bigger & bigger interval, until it does not throw an exception. Useful if you want to gracefully handle external services not being available, without actually building retries into your code. Works via Hollywood principle: Don't call us, we'll call you.
This file contains 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 | |
Class SomeClass() { | |
public function retry ($cb, $intervals = array(2, 4, 8, 16)) { | |
while ($intervals) { | |
if (!is_a($results = $cb(), 'Exception')) { | |
// good results, return them | |
return $results; | |
} | |
// failed, sleep for a larger & larger interval | |
$backoff = array_shift($intervals); | |
sleep($backoff); | |
} | |
// all retries failed :'( return the exception | |
return $results; | |
} | |
public function run () { | |
$results = $this->retry(function () use ($model, $findOptions) { | |
try { | |
// Your code that could throw an exception here | |
return $model->find('all', $findOptions); | |
} catch (Exception $e) { | |
// Return the exception to retry() | |
return $e; | |
} | |
}, $intervals = array(2, 4, 8, 16)); | |
// Config exponential backoff --^ | |
// You could also calculate it, but I think for most usecases it makes | |
// sense to have a limited and configurable backoff that gets eaten away. | |
// Also less prone to bugs / endless loops. | |
if (is_a($results, 'Exception') { | |
printf( | |
'Sorry, but even after %d tries in %d seconds I still got the Exception "%s"', | |
count($intervals), | |
array_sum($intervals), | |
$e->getMessage() | |
); | |
} else { | |
printf('Some nice results!'); | |
print_r($results); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment