From 69422ffaa42cda7d2881c5925cab17e224e3f9a3 Mon Sep 17 00:00:00 2001 From: Andy Heathershaw Date: Wed, 11 Sep 2019 14:59:25 +0100 Subject: [PATCH] Backblaze #135 - implemented a retry and backoff period for 500/503 errors --- app/Exceptions/BackblazeRetryException.php | 25 +++++++++++++++++ app/Services/BackblazeB2Service.php | 32 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 app/Exceptions/BackblazeRetryException.php diff --git a/app/Exceptions/BackblazeRetryException.php b/app/Exceptions/BackblazeRetryException.php new file mode 100644 index 0000000..557ebfd --- /dev/null +++ b/app/Exceptions/BackblazeRetryException.php @@ -0,0 +1,25 @@ +innerException; + } + + public function __construct($httpCode, \Exception $innerException) + { + parent::__construct('Backblaze requested to retry the request'); + + $this->innerException = $innerException; + } +} \ No newline at end of file diff --git a/app/Services/BackblazeB2Service.php b/app/Services/BackblazeB2Service.php index 2ffb95c..57149ee 100644 --- a/app/Services/BackblazeB2Service.php +++ b/app/Services/BackblazeB2Service.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Exceptions\BackblazeRetryException; use Illuminate\Support\Facades\Log; class BackblazeB2Service @@ -238,6 +239,27 @@ class BackblazeB2Service } private function sendRequest($url, $method = 'GET', $postData = null, array $postOptions = []) + { + $exponentialBackoff = 1; + $numberOfRetries = 5; // this effectively gives us 31 seconds of retries (1+2+4+8+16) + $numberOfTimesTried = 0; + + while ($numberOfTimesTried < $numberOfRetries) + { + try + { + return $this->sendRequestReal($url, $method, $postData, $postOptions); + } + catch (BackblazeRetryException $ex) + { + // Keep backing off + $exponentialBackoff *= $exponentialBackoff; + $numberOfTimesTried++; + } + } + } + + private function sendRequestReal($url, $method = 'GET', $postData = null, array $postOptions = []) { $postOptions = array_merge( [ @@ -298,7 +320,15 @@ class BackblazeB2Service Log::info(sprintf('Received HTTP code %d', $httpCode)); Log::debug($result); - if ($httpCode != 200 && $httpCode != 304) + // According to the Backblaze B2 Protocol, if we get a 500/503, we should retry the request + if ($httpCode == 500 || $httpCode == 503) + { + throw new BackblazeRetryException( + $httpCode, + new \Exception(sprintf('Exception from Backblaze B2: %s', $result)) + ); + } + else if ($httpCode != 200 && $httpCode != 304) { throw new \Exception(sprintf('Exception from Backblaze B2: %s', $result)); }