PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / libraries / http / client-common / PluginChain.php

PluginChain.php in DecaLog 4.4.0, at includes/libraries/http/client-common/PluginChain.php

62 lines 1.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Http\Client\Common;
6
7 use Http\Client\Common\Exception\LoopException;
8 use Http\Promise\Promise;
9 use Psr\Http\Message\RequestInterface;
10
11 final class PluginChain
12 {
13 /** @var Plugin[] */
14 private $plugins;
15
16 /** @var callable(RequestInterface): Promise */
17 private $clientCallable;
18
19 /** @var int */
20 private $maxRestarts;
21
22 /** @var int */
23 private $restarts = 0;
24
25 /**
26 * @param Plugin[] $plugins A plugin chain
27 * @param callable(RequestInterface): Promise $clientCallable Callable making the HTTP call
28 * @param array{'max_restarts'?: int} $options
29 */
30 public function __construct(array $plugins, callable $clientCallable, array $options = [])
31 {
32 $this->plugins = $plugins;
33 $this->clientCallable = $clientCallable;
34 $this->maxRestarts = (int) ($options['max_restarts'] ?? 0);
35 }
36
37 private function createChain(): callable
38 {
39 $lastCallable = $this->clientCallable;
40 $reversedPlugins = \array_reverse($this->plugins);
41
42 foreach ($reversedPlugins as $plugin) {
43 $lastCallable = function (RequestInterface $request) use ($plugin, $lastCallable) {
44 return $plugin->handleRequest($request, $lastCallable, $this);
45 };
46 }
47
48 return $lastCallable;
49 }
50
51 public function __invoke(RequestInterface $request): Promise
52 {
53 if ($this->restarts > $this->maxRestarts) {
54 throw new LoopException('Too many restarts in plugin client', $request);
55 }
56
57 ++$this->restarts;
58
59 return $this->createChain()($request);
60 }
61 }
62