A connection pool is a group of connections. When you ask Hyper to make a request, it will first look in the connection pool for a connection that it can reuse. If there's no connection available for reuse, then Hyper will create a new connection and use that for the request.
After the request finishes using the connection, Hyper will check to see if the connection can be reused; if it can be reused, the connection will be put into the connection pool for a later request to reuse.
This means that if you have code that does:
async fn do_many_gets(client: &hyper::client::Client) -> Result<(), Error> {
handle_response(client.get(URI).await?);
handle_response(client.get(URI).await?);
handle_response(client.get(URI).await?);
Ok(())
}
then Hyper will make one connection to the server specified by URI
(in the successful case, where the server supports connection reuse), and reuse it for each subsequent request. You thus get 3 requests on a single connection.
If we change the code to look like:
async fn do_many_gets(client: &hyper::client::Client) -> Result<(), Error> {
handle_response_pair(try_join(client.get(URI), client.get(URI)).await?);
handle_response_pair(try_join(client.get(URI), client.get(URI)).await?);
handle_response_pair(try_join(client.get(URI), client.get(URI)).await?);
Ok(())
}
Hyper will now make 2 connections to the server for the first pair of concurrent requests, but will reuse both connections (in the successful reuse case) for the second and third pair of concurrent requests. You thus get 2 connections to the server, each of which is used for 3 requests.
This means that in real code, the number of connections to a given host is bounded by the number of concurrent requests you're making to that host, but sequential requests can reuse existing connections from the connection pool.