diff vendor/guzzlehttp/guzzle/src/RetryMiddleware.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/guzzlehttp/guzzle/src/RetryMiddleware.php	Wed Nov 29 16:09:58 2017 +0000
@@ -0,0 +1,112 @@
+<?php
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Promise\RejectedPromise;
+use GuzzleHttp\Psr7;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Middleware that retries requests based on the boolean result of
+ * invoking the provided "decider" function.
+ */
+class RetryMiddleware
+{
+    /** @var callable  */
+    private $nextHandler;
+
+    /** @var callable */
+    private $decider;
+
+    /**
+     * @param callable $decider     Function that accepts the number of retries,
+     *                              a request, [response], and [exception] and
+     *                              returns true if the request is to be
+     *                              retried.
+     * @param callable $nextHandler Next handler to invoke.
+     * @param callable $delay       Function that accepts the number of retries
+     *                              and [response] and returns the number of
+     *                              milliseconds to delay.
+     */
+    public function __construct(
+        callable $decider,
+        callable $nextHandler,
+        callable $delay = null
+    ) {
+        $this->decider = $decider;
+        $this->nextHandler = $nextHandler;
+        $this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
+    }
+
+    /**
+     * Default exponential backoff delay function.
+     *
+     * @param $retries
+     *
+     * @return int
+     */
+    public static function exponentialDelay($retries)
+    {
+        return (int) pow(2, $retries - 1);
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param array            $options
+     *
+     * @return PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        if (!isset($options['retries'])) {
+            $options['retries'] = 0;
+        }
+
+        $fn = $this->nextHandler;
+        return $fn($request, $options)
+            ->then(
+                $this->onFulfilled($request, $options),
+                $this->onRejected($request, $options)
+            );
+    }
+
+    private function onFulfilled(RequestInterface $req, array $options)
+    {
+        return function ($value) use ($req, $options) {
+            if (!call_user_func(
+                $this->decider,
+                $options['retries'],
+                $req,
+                $value,
+                null
+            )) {
+                return $value;
+            }
+            return $this->doRetry($req, $options, $value);
+        };
+    }
+
+    private function onRejected(RequestInterface $req, array $options)
+    {
+        return function ($reason) use ($req, $options) {
+            if (!call_user_func(
+                $this->decider,
+                $options['retries'],
+                $req,
+                null,
+                $reason
+            )) {
+                return \GuzzleHttp\Promise\rejection_for($reason);
+            }
+            return $this->doRetry($req, $options);
+        };
+    }
+
+    private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
+    {
+        $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);
+
+        return $this($request, $options);
+    }
+}