Skip to content

Commit 86b2d1a

Browse files
committed
revert HttpClientPoolItem interface
1 parent a177902 commit 86b2d1a

File tree

7 files changed

+152
-178
lines changed

7 files changed

+152
-178
lines changed

spec/HttpClientPool/HttpClientPoolItemImplSpec.php renamed to spec/HttpClientPool/HttpClientPoolItemSpec.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Psr\Http\Message\ResponseInterface;
1515
use Http\Client\Exception\RequestException;
1616

17-
class HttpClientPoolItemImplSpec extends ObjectBehavior
17+
class HttpClientPoolItemSpec extends ObjectBehavior
1818
{
1919
public function let(HttpClient $httpClient)
2020
{

spec/HttpClientPool/LeastUsedClientPoolSpec.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace spec\Http\Client\Common\HttpClientPool;
44

55
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
6-
use Http\Client\Common\HttpClientPool\HttpClientPoolItemImpl;
76
use Http\Client\HttpAsyncClient;
87
use Http\Client\HttpClient;
98
use Http\Promise\Promise;
@@ -66,7 +65,7 @@ public function it_throw_exception_if_no_more_enable_client(HttpClient $client,
6665

6766
public function it_reenable_client(HttpClient $client, RequestInterface $request)
6867
{
69-
$this->addHttpClient(new HttpClientPoolItemImpl($client->getWrappedObject(), 0));
68+
$this->addHttpClient(new HttpClientPoolItem($client->getWrappedObject(), 0));
7069
$client->sendRequest($request)->willThrow(HttpException::class);
7170

7271
$this->shouldThrow(HttpException::class)->duringSendRequest($request);

spec/HttpClientPool/RandomClientPoolSpec.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace spec\Http\Client\Common\HttpClientPool;
44

5-
use Http\Client\Common\HttpClientPool\HttpClientPoolItemImpl;
5+
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
66
use Http\Client\HttpAsyncClient;
77
use Http\Client\HttpClient;
88
use Http\Promise\Promise;
@@ -65,7 +65,7 @@ public function it_throw_exception_if_no_more_enable_client(HttpClient $client,
6565

6666
public function it_reenable_client(HttpClient $client, RequestInterface $request)
6767
{
68-
$this->addHttpClient(new HttpClientPoolItemImpl($client->getWrappedObject(), 0));
68+
$this->addHttpClient(new HttpClientPoolItem($client->getWrappedObject(), 0));
6969
$client->sendRequest($request)->willThrow(HttpException::class);
7070

7171
$this->shouldThrow(HttpException::class)->duringSendRequest($request);

spec/HttpClientPool/RoundRobinClientPoolSpec.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace spec\Http\Client\Common\HttpClientPool;
44

5-
use Http\Client\Common\HttpClientPool\HttpClientPoolItemImpl;
5+
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
66
use Http\Client\HttpAsyncClient;
77
use Http\Client\HttpClient;
88
use Http\Promise\Promise;
@@ -65,7 +65,7 @@ public function it_throw_exception_if_no_more_enable_client(HttpClient $client,
6565

6666
public function it_reenable_client(HttpClient $client, RequestInterface $request)
6767
{
68-
$this->addHttpClient(new HttpClientPoolItemImpl($client->getWrappedObject(), 0));
68+
$this->addHttpClient(new HttpClientPoolItem($client->getWrappedObject(), 0));
6969
$client->sendRequest($request)->willThrow(HttpException::class);
7070

7171
$this->shouldThrow(HttpException::class)->duringSendRequest($request);

src/HttpClientPool/HttpClientPool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ abstract class HttpClientPool implements HttpClientPoolInterface
2828
public function addHttpClient($client)
2929
{
3030
if (!$client instanceof HttpClientPoolItem) {
31-
$client = new HttpClientPoolItemImpl($client);
31+
$client = new HttpClientPoolItem($client);
3232
}
3333

3434
$this->clientPool[] = $client;

src/HttpClientPool/HttpClientPoolItem.php

Lines changed: 145 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
namespace Http\Client\Common\HttpClientPool;
44

5+
use Http\Client\Common\FlexibleHttpClient;
56
use Http\Client\HttpAsyncClient;
67
use Http\Client\HttpClient;
8+
use Psr\Http\Message\RequestInterface;
9+
use Http\Client\Exception;
10+
use Psr\Http\Message\ResponseInterface;
711

812
/**
913
* A HttpClientPoolItem represent a HttpClient inside a Pool.
@@ -12,27 +16,157 @@
1216
* It also keep tracks of the current number of open requests the client is currently being sending
1317
* (only usable for async method).
1418
*
19+
* This class is used internally in the client pools and is not supposed to be used anywhere else.
20+
*
21+
* @final
22+
*
23+
* @internal
24+
*
1525
* @author Joel Wurtz <joel.wurtz@gmail.com>
1626
*/
17-
interface HttpClientPoolItem extends HttpClient, HttpAsyncClient
27+
class HttpClientPoolItem implements HttpClient, HttpAsyncClient
1828
{
1929
/**
20-
* Whether this client is disabled or not.
30+
* @var int Number of request this client is currently sending
31+
*/
32+
private $sendingRequestCount = 0;
33+
34+
/**
35+
* @var \DateTime|null Time when this client has been disabled or null if enable
36+
*/
37+
private $disabledAt;
38+
39+
/**
40+
* Number of seconds until this client is enabled again after an error.
2141
*
22-
* Will also reactivate this client if possible
42+
* null: never reenable this client.
2343
*
24-
* @internal
44+
* @var int|null
45+
*/
46+
private $reenableAfter;
47+
48+
/**
49+
* @var FlexibleHttpClient A http client responding to async and sync request
50+
*/
51+
private $client;
52+
53+
/**
54+
* @param HttpClient|HttpAsyncClient $client
55+
* @param null|int $reenableAfter Number of seconds until this client is enabled again after an error
56+
*/
57+
public function __construct($client, $reenableAfter = null)
58+
{
59+
$this->client = new FlexibleHttpClient($client);
60+
$this->reenableAfter = $reenableAfter;
61+
}
62+
63+
/**
64+
* {@inheritdoc}
65+
*/
66+
public function sendRequest(RequestInterface $request): ResponseInterface
67+
{
68+
if ($this->isDisabled()) {
69+
throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
70+
}
71+
72+
try {
73+
$this->incrementRequestCount();
74+
$response = $this->client->sendRequest($request);
75+
$this->decrementRequestCount();
76+
} catch (Exception $e) {
77+
$this->disable();
78+
$this->decrementRequestCount();
79+
80+
throw $e;
81+
}
82+
83+
return $response;
84+
}
85+
86+
/**
87+
* {@inheritdoc}
88+
*/
89+
public function sendAsyncRequest(RequestInterface $request)
90+
{
91+
if ($this->isDisabled()) {
92+
throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
93+
}
94+
95+
$this->incrementRequestCount();
96+
97+
return $this->client->sendAsyncRequest($request)->then(function ($response) {
98+
$this->decrementRequestCount();
99+
100+
return $response;
101+
}, function ($exception) {
102+
$this->disable();
103+
$this->decrementRequestCount();
104+
105+
throw $exception;
106+
});
107+
}
108+
109+
/**
110+
* Whether this client is disabled or not.
25111
*
26-
* @return bool
112+
* If the client was disabled, calling this method checks if the client can
113+
* be reenabled and if so enables it.
27114
*/
28-
public function isDisabled();
115+
public function isDisabled(): bool
116+
{
117+
if (null !== $this->reenableAfter && null !== $this->disabledAt) {
118+
// Reenable after a certain time
119+
$now = new \DateTime();
120+
121+
if (($now->getTimestamp() - $this->disabledAt->getTimestamp()) >= $this->reenableAfter) {
122+
$this->enable();
123+
124+
return false;
125+
}
126+
127+
return true;
128+
}
129+
130+
return null !== $this->disabledAt;
131+
}
29132

30133
/**
31134
* Get current number of request that are currently being sent by the underlying HTTP client.
32-
*
33-
* @internal
34-
*
35-
* @return int
36135
*/
37-
public function getSendingRequestCount();
136+
public function getSendingRequestCount(): int
137+
{
138+
return $this->sendingRequestCount;
139+
}
140+
141+
/**
142+
* Increment the request count.
143+
*/
144+
private function incrementRequestCount()
145+
{
146+
++$this->sendingRequestCount;
147+
}
148+
149+
/**
150+
* Decrement the request count.
151+
*/
152+
private function decrementRequestCount()
153+
{
154+
--$this->sendingRequestCount;
155+
}
156+
157+
/**
158+
* Enable the current client.
159+
*/
160+
private function enable()
161+
{
162+
$this->disabledAt = null;
163+
}
164+
165+
/**
166+
* Disable the current client.
167+
*/
168+
private function disable()
169+
{
170+
$this->disabledAt = new \DateTime('now');
171+
}
38172
}

0 commit comments

Comments
 (0)