Just wanted to share something I'm using on a daily basis...
We all know that external APIs sometimes can be slow and unreliable. It's quite annoying to guard any call to an external API with try...catch block so here's my PHP 5.3 only "solution" to this problem... Obviously if external service is down it's not going to magically fix it but it's going to retry a few times before returning false.
Here's an example:
$response = null;
$success = retry(3, function() use ($api, &$response) {
$response = $api->getSomething();
});
I think it's pretty obvious what this function does. Usually your external service handling class will throw an exception in case HTTP connection has timed out or reponse it's received is not valid. retry will catch that exception (or it can only catch exceptions of specified types) and will retry again after a certain delay (you can specify how many times you want it to retry before givinig up).
Here's the retry function itself:
/**
* Calls the callback function and in the case if exception is thrown retries
* a given number of times. Returns true on success.
*
* @param numeric $retries
* @param callback $callback
* @param array $exceptions
* @return bool
*/
function retry($retries, $callback, array $exceptions = null) {
if (!is_callable($callback)) {
throw new Bi_Exception('Argument 2 must be a valid callback');
}
$sleep = 1;
while ($retries--) {
try {
$callback();
return true;
}
catch (Exception $e) {
sleep($sleep);
$sleep *= 2;
}
}
if (is_array($exceptions)) {
$should_throw = true;
foreach ($exceptions as $exception_type) {
if (is_a($e, $exception_type) || is_subclass_of($e, $exception_type)) {
$should_throw = false;
break;
}
}
if ($should_throw) {
throw $e;
}
}
return false;
}