Skip to content

Commit 2914928

Browse files
committed
Make class final, add test for pool item, set protected method
1 parent 133c069 commit 2914928

File tree

5 files changed

+224
-11
lines changed

5 files changed

+224
-11
lines changed

spec/HttpClientPoolItemSpec.php

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
<?php
2+
3+
namespace spec\Http\Client\Common;
4+
5+
use Http\Client\Exception;
6+
use Http\Client\Exception\TransferException;
7+
use Http\Client\HttpAsyncClient;
8+
use Http\Client\HttpClient;
9+
use Http\Promise\Promise;
10+
use Http\Promise\RejectedPromise;
11+
use PhpSpec\ObjectBehavior;
12+
use Prophecy\Argument;
13+
use Psr\Http\Message\RequestInterface;
14+
use Psr\Http\Message\ResponseInterface;
15+
16+
class HttpClientPoolItemSpec extends ObjectBehavior
17+
{
18+
public function let(HttpClient $httpClient)
19+
{
20+
$this->beConstructedWith($httpClient);
21+
}
22+
23+
public function it_is_an_http_client()
24+
{
25+
$this->shouldImplement('Http\Client\HttpClient');
26+
}
27+
28+
public function it_is_an_async_http_client()
29+
{
30+
$this->shouldImplement('Http\Client\HttpAsyncClient');
31+
}
32+
33+
public function it_sends_request(HttpClient $httpClient, RequestInterface $request, ResponseInterface $response)
34+
{
35+
$httpClient->sendRequest($request)->willReturn($response);
36+
37+
$this->sendRequest($request)->shouldReturn($response);
38+
}
39+
40+
public function it_sends_async_request(HttpAsyncClient $httpAsyncClient, RequestInterface $request, Promise $promise)
41+
{
42+
$this->beConstructedWith($httpAsyncClient);
43+
44+
$httpAsyncClient->sendAsyncRequest($request)->willReturn($promise);
45+
$promise->then(Argument::type('callable'), Argument::type('callable'))->willReturn($promise);
46+
47+
$this->sendAsyncRequest($request)->shouldReturn($promise);
48+
}
49+
50+
public function it_disable_himself_on_send_request(HttpClient $httpClient, RequestInterface $request)
51+
{
52+
$exception = new TransferException();
53+
$httpClient->sendRequest($request)->willThrow($exception);
54+
$this->shouldThrow($exception)->duringSendRequest($request);
55+
$this->isDisabled()->shouldReturn(true);
56+
$this->shouldThrow('Http\Client\Exception\RequestException')->duringSendRequest($request);
57+
}
58+
59+
public function it_disable_himself_on_send_async_request(HttpAsyncClient $httpAsyncClient, RequestInterface $request)
60+
{
61+
$this->beConstructedWith($httpAsyncClient);
62+
63+
$promise = new RejectedPromise(new TransferException());
64+
$httpAsyncClient->sendAsyncRequest($request)->willReturn($promise);
65+
66+
$this->sendAsyncRequest($request)->shouldReturnAnInstanceOf('Http\Promise\RejectedPromise');
67+
$this->isDisabled()->shouldReturn(true);
68+
$this->shouldThrow('Http\Client\Exception\RequestException')->duringSendAsyncRequest($request);
69+
}
70+
71+
public function it_reactivate_himself_on_send_request(HttpClient $httpClient, RequestInterface $request)
72+
{
73+
$this->beConstructedWith($httpClient, 0);
74+
75+
$exception = new TransferException();
76+
$httpClient->sendRequest($request)->willThrow($exception);
77+
78+
$this->shouldThrow($exception)->duringSendRequest($request);
79+
$this->isDisabled()->shouldReturn(false);
80+
$this->shouldThrow($exception)->duringSendRequest($request);
81+
}
82+
83+
public function it_reactivate_himself_on_send_async_request(HttpAsyncClient $httpAsyncClient, RequestInterface $request)
84+
{
85+
$this->beConstructedWith($httpAsyncClient, 0);
86+
87+
$promise = new RejectedPromise(new TransferException());
88+
$httpAsyncClient->sendAsyncRequest($request)->willReturn($promise);
89+
90+
$this->sendAsyncRequest($request)->shouldReturnAnInstanceOf('Http\Promise\RejectedPromise');
91+
$this->isDisabled()->shouldReturn(false);
92+
$this->sendAsyncRequest($request)->shouldReturnAnInstanceOf('Http\Promise\RejectedPromise');
93+
}
94+
95+
public function it_increments_request_count(HttpAsyncClient $httpAsyncClient, RequestInterface $request, ResponseInterface $response)
96+
{
97+
$this->beConstructedWith($httpAsyncClient, 0);
98+
99+
$promise = new NotResolvingPromise($response->getWrappedObject());
100+
$httpAsyncClient->sendAsyncRequest($request)->willReturn($promise);
101+
102+
$this->getSendingRequestCount()->shouldReturn(0);
103+
$this->sendAsyncRequest($request)->shouldReturn($promise);
104+
$this->getSendingRequestCount()->shouldReturn(1);
105+
$this->sendAsyncRequest($request)->shouldReturn($promise);
106+
$this->getSendingRequestCount()->shouldReturn(2);
107+
}
108+
109+
public function it_decrements_request_count(HttpAsyncClient $httpAsyncClient, RequestInterface $request, ResponseInterface $response)
110+
{
111+
$this->beConstructedWith($httpAsyncClient, 0);
112+
113+
$promise = new NotResolvingPromise($response->getWrappedObject());
114+
$httpAsyncClient->sendAsyncRequest($request)->willReturn($promise);
115+
116+
$this->getSendingRequestCount()->shouldReturn(0);
117+
$this->sendAsyncRequest($request)->shouldReturn($promise);
118+
$this->getSendingRequestCount()->shouldReturn(1);
119+
120+
$promise->wait(false);
121+
122+
$this->getSendingRequestCount()->shouldReturn(0);
123+
}
124+
}
125+
126+
class NotResolvingPromise implements Promise
127+
{
128+
private $queue = [];
129+
130+
private $state = Promise::PENDING;
131+
132+
private $response;
133+
134+
private $exception;
135+
136+
public function __construct(ResponseInterface $response = null, Exception $exception = null)
137+
{
138+
$this->response = $response;
139+
$this->exception = $exception;
140+
}
141+
142+
public function then(callable $onFulfilled = null, callable $onRejected = null)
143+
{
144+
$this->queue[] = [
145+
$onFulfilled,
146+
$onRejected,
147+
];
148+
149+
return $this;
150+
}
151+
152+
public function getState()
153+
{
154+
return $this->state;
155+
}
156+
157+
public function wait($unwrap = true)
158+
{
159+
if ($this->state === Promise::FULFILLED) {
160+
if (!$unwrap) {
161+
return;
162+
}
163+
164+
return $this->response;
165+
}
166+
167+
if ($this->state === Promise::REJECTED) {
168+
if (!$unwrap) {
169+
return;
170+
}
171+
172+
throw $this->exception;
173+
}
174+
175+
while (count($this->queue) > 0) {
176+
$callbacks = array_shift($this->queue);
177+
178+
if ($this->response !== null) {
179+
try {
180+
$this->response = $callbacks[0]($this->response);
181+
$this->exception = null;
182+
} catch (Exception $exception) {
183+
$this->response = null;
184+
$this->exception = $exception;
185+
}
186+
} elseif ($this->exception !== null) {
187+
try {
188+
$this->response = $callbacks[1]($this->exception);
189+
$this->exception = null;
190+
} catch (Exception $exception) {
191+
$this->response = null;
192+
$this->exception = $exception;
193+
}
194+
}
195+
}
196+
197+
if ($this->response !== null) {
198+
$this->state = Promise::FULFILLED;
199+
200+
if ($unwrap) {
201+
return $this->response;
202+
}
203+
}
204+
205+
if ($this->exception !== null) {
206+
$this->state = Promise::REJECTED;
207+
208+
if ($unwrap) {
209+
throw $this->exception;
210+
}
211+
}
212+
}
213+
}

src/HttpClientPool/LeastUsedClientPool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
*
1414
* @author Joel Wurtz <[email protected]>
1515
*/
16-
class LeastUsedClientPool extends HttpClientPool
16+
final class LeastUsedClientPool extends HttpClientPool
1717
{
1818
/**
1919
* {@inheritdoc}
2020
*/
21-
public function chooseHttpClient()
21+
protected function chooseHttpClient()
2222
{
2323
$clientPool = array_filter($this->clientPool, function (HttpClientPoolItem $clientPoolItem) {
2424
return !$clientPoolItem->isDisabled();

src/HttpClientPool/RandomClientPool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
*
1212
* @author Joel Wurtz <[email protected]>
1313
*/
14-
class RandomClientPool extends HttpClientPool
14+
final class RandomClientPool extends HttpClientPool
1515
{
1616
/**
1717
* {@inheritdoc}
1818
*/
19-
public function chooseHttpClient()
19+
protected function chooseHttpClient()
2020
{
2121
$clientPool = array_filter($this->clientPool, function (HttpClientPoolItem $clientPoolItem) {
2222
return !$clientPoolItem->isDisabled();

src/HttpClientPool/RoundRobinClientPool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
*
1111
* @author Joel Wurtz <[email protected]>
1212
*/
13-
class RoundRobinClientPool extends HttpClientPool
13+
final class RoundRobinClientPool extends HttpClientPool
1414
{
1515
/**
1616
* {@inheritdoc}
1717
*/
18-
public function chooseHttpClient()
18+
protected function chooseHttpClient()
1919
{
2020
$last = current($this->clientPool);
2121

src/HttpClientPoolItem.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,39 +128,39 @@ public function getSendingRequestCount()
128128
*
129129
* @return \DateTime|null
130130
*/
131-
protected function getDisabledAt()
131+
private function getDisabledAt()
132132
{
133133
return $this->disabledAt;
134134
}
135135

136136
/**
137137
* Increment the request count.
138138
*/
139-
protected function incrementRequestCount()
139+
private function incrementRequestCount()
140140
{
141141
++$this->sendingRequestCount;
142142
}
143143

144144
/**
145145
* Decrement the request count.
146146
*/
147-
protected function decrementRequestCount()
147+
private function decrementRequestCount()
148148
{
149149
--$this->sendingRequestCount;
150150
}
151151

152152
/**
153153
* Enable the current client.
154154
*/
155-
protected function enable()
155+
private function enable()
156156
{
157157
$this->disabledAt = null;
158158
}
159159

160160
/**
161161
* Disable the current client.
162162
*/
163-
protected function disable()
163+
private function disable()
164164
{
165165
$this->disabledAt = new \DateTime('now');
166166
}

0 commit comments

Comments
 (0)