Skip to content

Add documention on http client pool #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions components/client-common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,74 @@ PluginClient
------------

See :doc:`/plugins/introduction`

HttpClientPool
--------------

The ``HttpClientPool`` allows to balance requests between a pool of ``HttpClient`` and/or ``HttpAsyncClient``.

The use cases are:

- Using a cluster (like an Elasticsearch service with multiple master nodes)
- Using fallback servers with the combination of the ``RetryPlugin`` (see :doc:`/plugins/retry`)

You can attach HTTP clients to this kind of client by using the ``addHttpClient`` method::

use Http\Client\Common\HttpClientPool\LeastUsedClientPool;
use Http\Discovery\HttpAsyncClientDiscovery;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;

$messageFactory = MessageFactoryDiscovery::find();

$httpClient = HttpClientDiscovery::find();
$httpAsyncClient = HttpAsyncClientDiscovery::find();

$httpClientPool = new LeastUsedClientPool();
$httpClientPool->addHttpClient($httpClient);
$httpClientPool->addHttpClient($httpAsyncClient);

$httpClientPool->sendRequest($messageFactory->createRequest('GET', 'http://example.com/update'));

Clients added to the pool are decorated with the ``HttpClientPoolItem`` class unless they already are an instance of this class.
The pool item class lets the pool be aware of the number of requests currently being processed by that client.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge this paragraph with the paragraph above. We are still talking about the pool item class.

It is also used to deactivate clients when they receive errors.
Deactivated clients can be reactivated after a certain amount of time, however, by default, they stay deactivated forever.
To enable the behavior, wrap the clients with the ``HttpClientPoolItem`` class yourself and specify the re-enable timeout::

// Reactivate after 30 seconds
$httpClientPool->addHttpClient(new HttpClientPoolItem($httpClient, 30));
// Reactivate after each call
$httpClientPool->addHttpClient(new HttpClientPoolItem($httpClient, 0));
// Never reactivate the client (default)
$httpClientPool->addHttpClient(new HttpClientPoolItem($httpClient, null));

``HttpClientPool`` is abstract. There are three concrete implementations with specific strategies on how to choose clients:

LeastUsedClientPool
*******************

``LeastUsedClientPool`` choose the client with the fewest requests in progress. As it sounds the best strategy for
sending a request on a pool of clients, this strategy has some limitations: :

- The counter is not shared between PHP process, so this strategy is not so useful in a web context, however it will make
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this specific to this strategy? is it not the same for round robin?

Copy link
Member Author

@joelwurtz joelwurtz Aug 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RoundRobin does not use the counter of items, but a selector on the pool, which his, indeed, not shared across process (but not really the same IMO).

better sense in a PHP command line context.
- This pool only makes sense with asynchronous clients. If you use ``sendRequest``, the call is blocking, and the pool
will only ever use the first client as its request count will be 0 once ``sendRequest`` finished.

A deactivated client will be removed for the pool until it is reactivated, if none are available it will throw a
``NotFoundHttpClientException``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes me wonder if we should have an option to ignore deactivated if no active client is found at all. otherwise there is a high risk of ending up with no clients if there was a short outage and we tried with each client.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a configuration per client, but we can add an option to set the default timer when we need to instantiate a HttpClientPoolItem (on the add method)

FYI on the reactivate param : null = never reactivate, 0 = reactivate after each fail, 1+ = number of seconds before reactivation of the client

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be mentioned in the doc


RoundRobinClientPool
********************

``RoundRobinClientPool`` keeps an internal pointer on the pool. At each call the pointer is moved to the next client, if
the current client is disabled it will move to the next client, and if none are available it will throw a
``NotFoundHttpClientException``

The pointer is not shared across PHP processes, so for each new one it will always start on the first client.

RandomClientPool
****************

``RandomClientPool`` randomly choose an available client, throw a ``NotFoundHttpClientException`` if none are available.
1 change: 1 addition & 0 deletions spelling_word_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ multipart
param
params
profiler
PHP
Puli
rebase
Semver
Expand Down