Mercurial > hg > isophonics-drupal-site
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 } |