diff --git a/src/Middleware/RetryMiddleware.php b/src/Middleware/RetryMiddleware.php new file mode 100644 index 000000000..86b7091ec --- /dev/null +++ b/src/Middleware/RetryMiddleware.php @@ -0,0 +1,97 @@ +<?php +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Google\Auth\Middleware; + +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * RetryMiddleware is a Guzzle Middleware that allows for retrying certain error + * codes automatically. + * + * Requests are accessed using the Simple API access developer key. + */ +class RetryMiddleware +{ + private $retryAttempts; + + /** + * Creates a new RetryMiddleware. + * + * @param array $config { + * Configuration array + * + * @type int $retryAttempts number of retry attempts. + * } + */ + public function __construct(array $config = []) + { + if (!isset($config['retryAttempts'])) { + throw new \InvalidArgumentException('requires retryAttempts to be set'); + } + + $this->retryAttempts = $config['retryAttempts']; + } + + /** + * Retry the response if it has retryable error codes. + * + * use Google\Auth\Middleware\AuthTokenMiddleware; + * use Google\Auth\Middleware\RetryMiddleware; + * use Google\Auth\OAuth2; + * use GuzzleHttp\Client; + * use GuzzleHttp\HandlerStack; + * + * $config = [..<oauth config param>.]; + * $oauth2 = new OAuth2($config) + * $authMiddleware = new AuthTokenMiddleware($oauth2); + * $retryMiddleware = new RetryMiddleware(['retryAttempts' => 3]); + * $stack = HandlerStack::create(); + * $stack->push($authMiddleware); + * $stack->push($retryMiddleware); + * + * $client = new Client([ + * 'handler' => $stack, + * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', + * 'auth' => 'google_auth' // authorize all requests + * ]); + * + * $res = $client->get('myproject/taskqueues/myqueue'); + * + * @param callable $handler + * @return \Closure + */ + public function __invoke(callable $handler) + { + return function (RequestInterface $request, array $options) use ($handler) { + $response = $handler($request, $options); + for ($attempts = 0; $attempts < $this->retryAttempts; $attempts++) { + if ($this->isRetryable($response)) { + $response = $handler($request, $options); + } + } + return $response; + }; + } + + private function isRetryable(ResponseInterface $response) + { + // no-op for now, this is a Proof of Concept! + return false; + } +}