Skip to content

Commit

Permalink
revert HttpClientPoolItem interface
Browse files Browse the repository at this point in the history
  • Loading branch information
dbu committed Dec 13, 2018
1 parent a177902 commit 67a7b24
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 178 deletions.
Expand Up @@ -14,7 +14,7 @@
use Psr\Http\Message\ResponseInterface;
use Http\Client\Exception\RequestException;

class HttpClientPoolItemImplSpec extends ObjectBehavior
class HttpClientPoolItemSpec extends ObjectBehavior
{
public function let(HttpClient $httpClient)
{
Expand Down
4 changes: 2 additions & 2 deletions spec/HttpClientPool/LeastUsedClientPoolSpec.php
Expand Up @@ -3,7 +3,7 @@
namespace spec\Http\Client\Common\HttpClientPool;

use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
use Http\Client\Common\HttpClientPool\HttpClientPoolItemImpl;
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\Promise\Promise;
Expand Down Expand Up @@ -66,7 +66,7 @@ public function it_throw_exception_if_no_more_enable_client(HttpClient $client,

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

$this->shouldThrow(HttpException::class)->duringSendRequest($request);
Expand Down
4 changes: 2 additions & 2 deletions spec/HttpClientPool/RandomClientPoolSpec.php
Expand Up @@ -2,7 +2,7 @@

namespace spec\Http\Client\Common\HttpClientPool;

use Http\Client\Common\HttpClientPool\HttpClientPoolItemImpl;
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\Promise\Promise;
Expand Down Expand Up @@ -65,7 +65,7 @@ public function it_throw_exception_if_no_more_enable_client(HttpClient $client,

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

$this->shouldThrow(HttpException::class)->duringSendRequest($request);
Expand Down
4 changes: 2 additions & 2 deletions spec/HttpClientPool/RoundRobinClientPoolSpec.php
Expand Up @@ -2,7 +2,7 @@

namespace spec\Http\Client\Common\HttpClientPool;

use Http\Client\Common\HttpClientPool\HttpClientPoolItemImpl;
use Http\Client\Common\HttpClientPool\HttpClientPoolItem;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Http\Promise\Promise;
Expand Down Expand Up @@ -65,7 +65,7 @@ public function it_throw_exception_if_no_more_enable_client(HttpClient $client,

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

$this->shouldThrow(HttpException::class)->duringSendRequest($request);
Expand Down
2 changes: 1 addition & 1 deletion src/HttpClientPool/HttpClientPool.php
Expand Up @@ -28,7 +28,7 @@ abstract class HttpClientPool implements HttpClientPoolInterface
public function addHttpClient($client)
{
if (!$client instanceof HttpClientPoolItem) {
$client = new HttpClientPoolItemImpl($client);
$client = new HttpClientPoolItem($client);
}

$this->clientPool[] = $client;
Expand Down
156 changes: 145 additions & 11 deletions src/HttpClientPool/HttpClientPoolItem.php
Expand Up @@ -2,8 +2,12 @@

namespace Http\Client\Common\HttpClientPool;

use Http\Client\Common\FlexibleHttpClient;
use Http\Client\HttpAsyncClient;
use Http\Client\HttpClient;
use Psr\Http\Message\RequestInterface;
use Http\Client\Exception;
use Psr\Http\Message\ResponseInterface;

/**
* A HttpClientPoolItem represent a HttpClient inside a Pool.
Expand All @@ -12,27 +16,157 @@
* It also keep tracks of the current number of open requests the client is currently being sending
* (only usable for async method).
*
* This class is used internally in the client pools and is not supposed to be used anywhere else.
*
* @final
*
* @internal
*
* @author Joel Wurtz <joel.wurtz@gmail.com>
*/
interface HttpClientPoolItem extends HttpClient, HttpAsyncClient
class HttpClientPoolItem implements HttpClient, HttpAsyncClient
{
/**
* Whether this client is disabled or not.
* @var int Number of request this client is currently sending
*/
private $sendingRequestCount = 0;

/**
* @var \DateTime|null Time when this client has been disabled or null if enable
*/
private $disabledAt;

/**
* Number of seconds until this client is enabled again after an error.
*
* Will also reactivate this client if possible
* null: never reenable this client.
*
* @internal
* @var int|null
*/
private $reenableAfter;

/**
* @var FlexibleHttpClient A http client responding to async and sync request
*/
private $client;

/**
* @param HttpClient|HttpAsyncClient $client
* @param null|int $reenableAfter Number of seconds until this client is enabled again after an error
*/
public function __construct($client, $reenableAfter = null)
{
$this->client = new FlexibleHttpClient($client);
$this->reenableAfter = $reenableAfter;
}

/**
* {@inheritdoc}
*/
public function sendRequest(RequestInterface $request): ResponseInterface
{
if ($this->isDisabled()) {
throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
}

try {
$this->incrementRequestCount();
$response = $this->client->sendRequest($request);
$this->decrementRequestCount();
} catch (Exception $e) {
$this->disable();
$this->decrementRequestCount();

throw $e;
}

return $response;
}

/**
* {@inheritdoc}
*/
public function sendAsyncRequest(RequestInterface $request)
{
if ($this->isDisabled()) {
throw new Exception\RequestException('Cannot send the request as this client has been disabled', $request);
}

$this->incrementRequestCount();

return $this->client->sendAsyncRequest($request)->then(function ($response) {
$this->decrementRequestCount();

return $response;
}, function ($exception) {
$this->disable();
$this->decrementRequestCount();

throw $exception;
});
}

/**
* Whether this client is disabled or not.
*
* @return bool
* If the client was disabled, calling this method checks if the client can
* be reenabled and if so enables it.
*/
public function isDisabled();
public function isDisabled(): bool
{
if (null !== $this->reenableAfter && null !== $this->disabledAt) {
// Reenable after a certain time
$now = new \DateTime();

if (($now->getTimestamp() - $this->disabledAt->getTimestamp()) >= $this->reenableAfter) {
$this->enable();

return false;
}

return true;
}

return null !== $this->disabledAt;
}

/**
* Get current number of request that are currently being sent by the underlying HTTP client.
*
* @internal
*
* @return int
*/
public function getSendingRequestCount();
public function getSendingRequestCount(): int
{
return $this->sendingRequestCount;
}

/**
* Increment the request count.
*/
private function incrementRequestCount()
{
++$this->sendingRequestCount;
}

/**
* Decrement the request count.
*/
private function decrementRequestCount()
{
--$this->sendingRequestCount;
}

/**
* Enable the current client.
*/
private function enable()
{
$this->disabledAt = null;
}

/**
* Disable the current client.
*/
private function disable()
{
$this->disabledAt = new \DateTime('now');
}
}

0 comments on commit 67a7b24

Please sign in to comment.