diff --git a/components/client-common.rst b/components/client-common.rst index 334e6bf..f5235ee 100644 --- a/components/client-common.rst +++ b/components/client-common.rst @@ -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. +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 + 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`` + +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. diff --git a/spelling_word_list.txt b/spelling_word_list.txt index 13540a6..51aef1a 100644 --- a/spelling_word_list.txt +++ b/spelling_word_list.txt @@ -21,6 +21,7 @@ multipart param params profiler +PHP Puli rebase Semver