VOOZH about

URL: https://deepwiki.com/hypervel/http-client/10.2-connection-management

⇱ Connection Management | hypervel/http-client | DeepWiki


Loading...
Menu

Connection Management

This document describes the connection management system in the Hypervel HTTP Client, which provides named connection configurations and connection pooling for efficient resource reuse across multiple HTTP requests.

Scope: This page covers connection registration, configuration, pooling architecture, and connection resolution. For information about configuring individual request options, see Request Configuration. For middleware and handler stack customization, see Middleware and Handler Stack.


Overview

The connection management system enables applications to define multiple named HTTP client configurations and automatically pool client connections for reuse. This architecture provides:

  • Named Connections: Pre-configured client settings that can be referenced by name
  • Connection Pooling: Automatic reuse of client instances to reduce overhead
  • Dynamic Configuration: Ability to override connection settings per-request
  • Isolation: Separate connection pools for different named connections

The system is built on three main components: Factory manages connection registration and resolution, PendingRequest specifies which connection to use, and ClientPoolProxy implements the pooling mechanism.

Sources: src/Factory.php1-526 src/PendingRequest.php163-170 src/ClientPoolProxy.php1-64


Connection Management Architecture


Diagram: Connection Management Component Structure

The Factory maintains three key data structures for connection management. The poolables array tracks which connection names should use pooling. The connections array caches resolved ClientPoolProxy instances for reuse. The connectionConfigs array stores configuration arrays for each named connection. When a PendingRequest builds its client, it passes its connection name to Factory::getClient(), which resolves the appropriate client instance.

Sources: src/Factory.php73-88 src/PendingRequest.php163-170 src/PendingRequest.php1033-1051


Named Connections

Named connections allow pre-configuration of HTTP client settings that can be reused across multiple requests. Each connection has a name and an associated configuration array.

Registering Connections

Connections are registered with the Factory using the registerConnection() method:


This method performs two operations:

  1. Adds the connection name to the poolables array via addPoolable()
  2. Stores the configuration via setConnectionConfig()

The configuration array can contain any Guzzle client options, pool configuration, or custom settings specific to the connection.

Sources: src/Factory.php436-444

Connection Configuration Storage

The Factory provides methods for managing connection configurations:

MethodPurposeReturn Type
getConnectionConfigs()Retrieve all connection configurationsarray
getConnectionConfig(string $name)Get configuration for specific connectionarray
setConnectionConfig(string $name, array $config)Set configuration for specific connectionstatic

These methods interact with the $connectionConfigs property, which is an associative array mapping connection names to configuration arrays.

Sources: src/Factory.php490-513

Using Named Connections

The PendingRequest class specifies which connection to use through the connection() method:


This method sets two properties:

  • $connection: The name of the connection to use
  • $connectionConfig: Optional configuration override for this specific request

When a configuration override is provided, it is merged with or replaces the registered connection configuration during client resolution.

Sources: src/PendingRequest.php1313-1334

Connection Properties in PendingRequest


Diagram: PendingRequest Connection Properties

The $connection property stores the connection name as a nullable string. The $connectionConfig property stores an optional configuration array that overrides or supplements the registered configuration. When buildClient() is called, these values are passed to the Factory for resolution.

Sources: src/PendingRequest.php163-170 src/PendingRequest.php1313-1334


Connection Pooling

Connection pooling enables efficient reuse of HTTP client instances across multiple requests, reducing the overhead of creating new client connections.

ClientPoolProxy Architecture

The ClientPoolProxy class extends PoolProxy from the hypervel/object-pool package and implements GuzzleHttp\ClientInterface:


Diagram: ClientPoolProxy Inheritance Structure

All ClientInterface methods are implemented by proxying calls through the inherited __call() method from PoolProxy. This delegation pattern allows the pool proxy to intercept method calls and route them to pooled client instances without duplicating interface implementation code.

Sources: src/ClientPoolProxy.php1-64

Pool Proxy Implementation Details

The ClientPoolProxy implements six methods from ClientInterface:

MethodSignaturePurpose
request()request(string $method, $uri, array $options): ResponseInterfaceSynchronous HTTP request
requestAsync()requestAsync(string $method, $uri, array $options): PromiseInterfaceAsynchronous HTTP request
send()send(RequestInterface $request, array $options): ResponseInterfaceSend PSR-7 request synchronously
sendAsync()sendAsync(RequestInterface $request, array $options): PromiseInterfaceSend PSR-7 request asynchronously
sendRequest()sendRequest(RequestInterface $request): ResponseInterfacePSR-18 HTTP client method
getConfig()getConfig(?string $option)Retrieve client configuration

Each method delegates to $this->__call(__FUNCTION__, func_get_args()), which invokes the base PoolProxy pooling logic.

Sources: src/ClientPoolProxy.php15-63

Pool Configuration

The Factory class declares the pool proxy class to use:


This property is used by the HasPoolProxy trait (from hypervel/object-pool) to create pool proxy instances. The pool configuration is passed as the third argument to createPoolProxy() during connection resolution.

Sources: src/Factory.php73


Connection Resolution Process

The connection resolution process determines which HTTP client instance to use for a request based on the connection name and configuration.

Resolution Flow


Diagram: Connection Resolution Sequence

The resolution process begins when PendingRequest::buildClient() calls Factory::getClient() with the connection name, handler stack, and optional configuration. The getClient() method delegates to resolve(), which implements the resolution logic.

Sources: src/Factory.php451-476 src/PendingRequest.php1033-1036

Resolution Logic

The Factory::resolve() method implements the following logic:


Resolution Steps:

  1. Null Connection: If $name is null, create a new non-pooled Client instance directly
  2. Validation: Verify the connection name exists in the $poolables array
  3. Cache Check: Use null coalescing assignment (??=) to return cached proxy if it exists
  4. Proxy Creation: Create new ClientPoolProxy with the connection name, client factory closure, and configuration
  5. Caching: Store the created proxy in $connections[$name] for future reuse

Sources: src/Factory.php461-476

Client Factory Methods

The Factory provides two methods for creating HTTP clients:

createClient(HandlerStack $handlerStack): ClientInterface

Creates a new Guzzle client instance with the provided handler stack:


This method is called either directly (for null connections) or indirectly through the factory closure passed to createPoolProxy().

createPoolProxy(string $name, callable $factory, array $config): ClientInterface

This method is inherited from the HasPoolProxy trait. It creates a new ClientPoolProxy instance using the specified pool proxy class, passing the connection name, client factory closure, and pool configuration.

Sources: src/Factory.php479-487


Configuration Merging

When a PendingRequest specifies a connection configuration override, the resolution process determines which configuration to use:


The resolution logic uses the configuration parameter ($config) if provided, otherwise falls back to the registered configuration from $connectionConfigs. This allows per-request configuration customization without modifying the registered connection settings.

Priority Order:

  1. Configuration passed to PendingRequest::connection()
  2. Configuration passed to Factory::getClient()
  3. Registered configuration from Factory::registerConnection()

Sources: src/Factory.php474 src/PendingRequest.php1316-1318


Integration with Request Execution

The connection management system integrates seamlessly with the request execution flow:


Diagram: Connection Management in Request Flow

When PendingRequest::send() executes, it calls sendRequest() which builds the client via buildClient(). The buildClient() method retrieves the connection name and configuration from the instance properties and passes them to Factory::getClient(). The factory resolves the appropriate client (pooled or non-pooled) and returns it. The sendRequest() method then uses the client to execute the HTTP request.

Sources: src/PendingRequest.php713-794 src/PendingRequest.php953-972 src/PendingRequest.php1033-1052


Reusable vs. Non-Reusable Clients

The PendingRequest class distinguishes between requests that require client reuse and those that don't:


A reusable client is required when:

  • A client has been explicitly set via setClient()
  • The request is asynchronous ($async === true)

When a reusable client is required, the getReusableClient() method ensures the same client instance is used across multiple operations:


This prevents recreating clients for asynchronous operations or when working with an explicitly configured client instance.

Sources: src/PendingRequest.php1041-1052


Usage Patterns

Basic Named Connection


Per-Request Configuration Override


Non-Pooled Anonymous Client


Setting Connection Configuration


Sources: src/Factory.php436-513 src/PendingRequest.php1313-1321