== Connection Pool

By default, `HttpClient` (`HttpClient.create()`) uses a shared `ConnectionProvider`. This `ConnectionProvider` is configured to create
a "`fixed`" connection pool per remote host (a remote host implies the combination of a hostname and its associated port number) with:

* `500` as the maximum number of active channels
* `1000` as the maximum number of further channel acquisition attempts allowed to be kept in a pending state
* The rest of the configurations are the defaults (check the system properties or the builder configurations below)

This means that the implementation creates a new channel if someone tries to acquire a channel
as long as less than `500` have been created and are managed by the pool.
When the maximum number of channels in the pool is reached, up to `1000` new attempts to
acquire a channel are delayed (pending) until a channel is returned to the pool again,
and further attempts are declined with an error.

{reactor-netty-github-repo}/reactor-netty-core/src/main/java/reactor/netty/ReactorNetty.java
[%unbreakable]
----
include::{core}/src/main/java/reactor/netty/ReactorNetty.java[lines=124..172]
----

When you need to change the default settings, you can configure the `ConnectionProvider` as follows:

{examples-link}/pool/config/Application.java
[%unbreakable]
----
include::{examples-dir}/pool/config/Application.java[lines=18..50]
----
<1> Configures the maximum time for a connection to stay idle to 20 seconds.
<2> Configures the maximum time for a connection to stay alive to 60 seconds.
<3> Configures the maximum time for the pending acquire operation to 60 seconds.
<4> Every two minutes, the connection pool is regularly checked for connections that are applicable for removal.

NOTE: Notice that only the default `HttpClient` (`HttpClient.create()`) uses `500` as the maximum number of active channels. In the example above, when
instantiating a custom `ConnectionProvider`, we are changing this value to `50` using `maxConnections`. Also, if you don't set this parameter the
default `maxConnections` is used (2 * available number of processors).

The following listing shows the available configurations:
[width="100%",options="header"]
|=======
| Configuration name | Description
| `disposeInactivePoolsInBackground` | When this option is enabled, connection pools are regularly checked in the background,
and those that are *empty* and been inactive for a specified time become eligible for disposal. Connection pool is considered
*empty* when there are no active connections, idle connections and pending acquisitions. By default, this background disposal of inactive pools is disabled.
| `disposeTimeout` | When `ConnectionProvider#dispose()` or `ConnectionProvider#disposeLater()` is called,
trigger a graceful shutdown for the connection pools, with this grace period timeout.
From there on, all calls for acquiring a connection will fail fast with an exception.
However, for the provided `Duration`, pending acquires will get a chance to be served.
Note: The rejection of new acquires and the grace timer start immediately,
irrespective of subscription to the `Mono` returned by `ConnectionProvider#disposeLater()`.
Subsequent calls return the same `Mono`, effectively getting notifications from the first graceful
shutdown call and ignoring subsequently provided timeouts. By default, dispose timeout is not specified.
| `evictInBackground` | When this option is enabled, each connection pool regularly checks for connections that are
eligible for removal according to eviction criteria like `maxIdleTime`. By default, this background eviction is disabled.
| `fifo` | Configure the connection pool so that if there are idle connections (i.e. pool is under-utilized),
the next acquire operation will get the `Least Recently Used` connection
(LRU, i.e. the connection that was released first among the current idle connections). Default leasing strategy.
| `lifo` | Configure the connection pool so that if there are idle connections (i.e. pool is under-utilized),
the next acquire operation will get the `Most Recently Used` connection
(MRU, i.e. the connection that was released last among the current idle connections).
| `maxConnections` | The maximum number of connections (per connection pool) before start pending. Default to
2 * available number of processors (but with a minimum value of 16).
| `maxIdleTime` | The time after which the channel is eligible to be closed when idle (resolution: ms). Default: max idle time is not specified.
| `maxLifeTime` | The total life time after which the channel is eligible to be closed (resolution: ms). Default: max life time is not specified.
| `metrics` | Enables/disables built-in integration with Micrometer. `ConnectionProvider.MeterRegistrar` can be provided
for integration with another metrics system. By default, metrics are not enabled.
| `pendingAcquireMaxCount` | The maximum number of extra attempts at acquiring a connection to keep in a pending queue.
If -1 is specified, the pending queue does not have upper limit. Default to 2 * max connections.
| `pendingAcquireTimeout` | The maximum time before which a pending acquire must complete, or a TimeoutException is
thrown (resolution: ms). If -1 is specified, no such timeout is applied. Default: 45 seconds.
|=======

NOTE: When you expect a high load, be cautious with a connection pool with a very high value for maximum connections. You might experience
`reactor.netty.http.client.PrematureCloseException` exception with a root cause "Connect Timeout" due
to too many concurrent connections opened/acquired.

If you need to disable the connection pool, you can apply the following configuration:

{examples-link}/pool/Application.java
[%unbreakable]
----
include::{examples-dir}/pool/Application.java[lines=18..49]
----

=== Disposing Connection Pool

- If you use the default `ConnectionProvider` provided by Reactor Netty, invoke
{javadoc}/reactor/netty/http/HttpResources.html[`HttpResources`]`#disposeLoopsAndConnections`/`#disposeLoopsAndConnectionsLater` method.

NOTE: Disposing `HttpResources` means that every client that is using it, will not be able to use it anymore!

- If you use custom `ConnectionProvider`, invoke {javadoc}/reactor/netty/resources/ConnectionProvider.html[`ConnectionProvider`]`#dispose`/`#disposeLater`/`#disposeWhen` method.

NOTE: Disposing the custom `ConnectionProvider` means that every client that is configured to use it, will not be able to use it anymore!

=== Metrics
The pooled `ConnectionProvider` supports built-in integration with https://micrometer.io/[`Micrometer`].
It exposes all metrics with a prefix of `reactor.netty.connection.provider`.

include::partial$conn-provider-metrics.adoc[]

The following table provides information for the HTTP client metrics when it is configured to serve `HTTP/2` traffic:

[width="100%",options="header"]
|=======
| metric name | type | description
| reactor.netty.connection.provider.active.streams | Gauge | The number of the active HTTP/2 streams.
See xref:observability.adoc#observability-metrics-active-streams[Active Streams]
| reactor.netty.connection.provider.pending.streams | Gauge | The number of requests that are waiting for opening HTTP/2 stream.
See xref:observability.adoc#observability-metrics-pending-streams[Pending Streams]
|=======

The following example enables that integration:

{examples-link}/pool/metrics/Application.java
[%unbreakable]
----
include::{examples-dir}/pool/metrics/Application.java[lines=18..45]
----
<1> Enables the built-in integration with Micrometer
