comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2 namespace GuzzleHttp;
3
4 use GuzzleHttp\Promise\PromiseInterface;
5 use GuzzleHttp\Promise\RejectedPromise;
6 use GuzzleHttp\Psr7;
7 use Psr\Http\Message\RequestInterface;
8 use Psr\Http\Message\ResponseInterface;
9
10 /**
11 * Middleware that retries requests based on the boolean result of
12 * invoking the provided "decider" function.
13 */
14 class RetryMiddleware
15 {
16 /** @var callable */
17 private $nextHandler;
18
19 /** @var callable */
20 private $decider;
21
22 /**
23 * @param callable $decider Function that accepts the number of retries,
24 * a request, [response], and [exception] and
25 * returns true if the request is to be
26 * retried.
27 * @param callable $nextHandler Next handler to invoke.
28 * @param callable $delay Function that accepts the number of retries
29 * and [response] and returns the number of
30 * milliseconds to delay.
31 */
32 public function __construct(
33 callable $decider,
34 callable $nextHandler,
35 callable $delay = null
36 ) {
37 $this->decider = $decider;
38 $this->nextHandler = $nextHandler;
39 $this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
40 }
41
42 /**
43 * Default exponential backoff delay function.
44 *
45 * @param $retries
46 *
47 * @return int
48 */
49 public static function exponentialDelay($retries)
50 {
51 return (int) pow(2, $retries - 1);
52 }
53
54 /**
55 * @param RequestInterface $request
56 * @param array $options
57 *
58 * @return PromiseInterface
59 */
60 public function __invoke(RequestInterface $request, array $options)
61 {
62 if (!isset($options['retries'])) {
63 $options['retries'] = 0;
64 }
65
66 $fn = $this->nextHandler;
67 return $fn($request, $options)
68 ->then(
69 $this->onFulfilled($request, $options),
70 $this->onRejected($request, $options)
71 );
72 }
73
74 private function onFulfilled(RequestInterface $req, array $options)
75 {
76 return function ($value) use ($req, $options) {
77 if (!call_user_func(
78 $this->decider,
79 $options['retries'],
80 $req,
81 $value,
82 null
83 )) {
84 return $value;
85 }
86 return $this->doRetry($req, $options, $value);
87 };
88 }
89
90 private function onRejected(RequestInterface $req, array $options)
91 {
92 return function ($reason) use ($req, $options) {
93 if (!call_user_func(
94 $this->decider,
95 $options['retries'],
96 $req,
97 null,
98 $reason
99 )) {
100 return \GuzzleHttp\Promise\rejection_for($reason);
101 }
102 return $this->doRetry($req, $options);
103 };
104 }
105
106 private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
107 {
108 $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);
109
110 return $this($request, $options);
111 }
112 }