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 / HttpClientPool / HttpClientPoolItem.php

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

182 lines 4.8 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\HttpClientPool;
6
7 use Http\Client\Common\FlexibleHttpClient;
8 use Http\Client\Exception;
9 use Http\Client\HttpAsyncClient;
10 use Http\Client\HttpClient;
11 use Psr\Http\Client\ClientInterface;
12 use Psr\Http\Message\RequestInterface;
13 use Psr\Http\Message\ResponseInterface;
14
15 /**
16 * A HttpClientPoolItem represent a HttpClient inside a Pool.
17 *
18 * It is disabled when a request failed and can be reenabled after a certain number of seconds.
19 * It also keep tracks of the current number of open requests the client is currently being sending
20 * (only usable for async method).
21 *
22 * This class is used internally in the client pools and is not supposed to be used anywhere else.
23 *
24 * @final
25 *
26 * @internal
27 *
28 * @author Joel Wurtz <joel.wurtz@gmail.com>
29 */
30 class HttpClientPoolItem implements HttpClient, HttpAsyncClient
31 {
32 /**
33 * @var int Number of request this client is currently sending
34 */
35 private $sendingRequestCount = 0;
36
37 /**
38 * @var \DateTime|null Time when this client has been disabled or null if enable
39 */
40 private $disabledAt;
41
42 /**
43 * Number of seconds until this client is enabled again after an error.
44 *
45 * null: never reenable this client.
46 *
47 * @var int|null
48 */
49 private $reenableAfter;
50
51 /**
52 * @var FlexibleHttpClient A http client responding to async and sync request
53 */
54 private $client;
55
56 /**
57 * @param ClientInterface|HttpAsyncClient $client
58 * @param int|null $reenableAfter Number of seconds until this client is enabled again after an error
59 */
60 public function __construct($client, int $reenableAfter = null)
61 {
62 if (!$client instanceof ClientInterface && !$client instanceof HttpAsyncClient) {
63 throw new \TypeError(
64 sprintf('%s::__construct(): Argument #1 ($client) must be of type %s|%s, %s given', self::class, ClientInterface::class, HttpAsyncClient::class, get_debug_type($client))
65 );
66 }
67
68 $this->client = new FlexibleHttpClient($client);
69 $this->reenableAfter = $reenableAfter;
70 }
71
72 /**
73 * {@inheritdoc}
74 */
75 public function sendRequest(RequestInterface $request): ResponseInterface
76 {
77 if ($this->isDisabled()) {
78 throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
79 }
80
81 try {
82 $this->incrementRequestCount();
83 $response = $this->client->sendRequest($request);
84 $this->decrementRequestCount();
85 } catch (Exception $e) {
86 $this->disable();
87 $this->decrementRequestCount();
88
89 throw $e;
90 }
91
92 return $response;
93 }
94
95 /**
96 * {@inheritdoc}
97 */
98 public function sendAsyncRequest(RequestInterface $request)
99 {
100 if ($this->isDisabled()) {
101 throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
102 }
103
104 $this->incrementRequestCount();
105
106 return $this->client->sendAsyncRequest($request)->then(function ($response) {
107 $this->decrementRequestCount();
108
109 return $response;
110 }, function ($exception) {
111 $this->disable();
112 $this->decrementRequestCount();
113
114 throw $exception;
115 });
116 }
117
118 /**
119 * Whether this client is disabled or not.
120 *
121 * If the client was disabled, calling this method checks if the client can
122 * be reenabled and if so enables it.
123 */
124 public function isDisabled(): bool
125 {
126 if (null !== $this->reenableAfter && null !== $this->disabledAt) {
127 // Reenable after a certain time
128 $now = new \DateTime();
129
130 if (($now->getTimestamp() - $this->disabledAt->getTimestamp()) >= $this->reenableAfter) {
131 $this->enable();
132
133 return false;
134 }
135
136 return true;
137 }
138
139 return null !== $this->disabledAt;
140 }
141
142 /**
143 * Get current number of request that are currently being sent by the underlying HTTP client.
144 */
145 public function getSendingRequestCount(): int
146 {
147 return $this->sendingRequestCount;
148 }
149
150 /**
151 * Increment the request count.
152 */
153 private function incrementRequestCount(): void
154 {
155 ++$this->sendingRequestCount;
156 }
157
158 /**
159 * Decrement the request count.
160 */
161 private function decrementRequestCount(): void
162 {
163 --$this->sendingRequestCount;
164 }
165
166 /**
167 * Enable the current client.
168 */
169 private function enable(): void
170 {
171 $this->disabledAt = null;
172 }
173
174 /**
175 * Disable the current client.
176 */
177 private function disable(): void
178 {
179 $this->disabledAt = new \DateTime('now');
180 }
181 }
182