ConnectionPool

public class ConnectionPool

A pool of re-usable, interchangeable Connection instances.

Using a ConnectionPool allows an application to acquire an existing Connection from the pool, use that connection to perform one or more SQL statements, and then release it for use elsewhere in the application.

The ConnectionPoolConfiguration used to create a ConnectionPool specifies the number of connections in the pool, how long a request for a connection will wait for a connection to become available, and other characteristics of the pool.

All connections in a ConnectionPool are created from the same ConnectionConfiguration. They also have the same ConnectionDelegate (if a delegate is specified). Consequently any connection in a pool is interchangeable with any other.

Use ConnectionPool.acquireConnection(completionHandler:) to request a connection from a ConnectionPool. This method is non-blocking: its completion handler is asynchronously executed when a connection is successfully allocated to the request or if an error occurs. To release the connection back to the pool, call ConnectionPool.releaseConnection(_:).

Alternately, use ConnectionPool.withConnection(completionHandler:) to acquire a connection that is automatically released after execution of the completion handler.

When a connection is released to a ConnectionPool, there should be no transaction underway. Pair each SQL BEGIN command with either a COMMIT or ROLLBACK command (or equivalently, use the Connection.beginTransaction(), Connection.commitTransaction(), and Connection.rollbackTransaction() methods).

In general, do not close a Connection acquired from a ConnectionPool. If a connection is closed (whether explicitly or because of an unrecoverable error) then, when that connection is released, it will be discarded from the pool, allowing a new connection to be created and added to the pool.

The ConnectionPool class is threadsafe: multiple threads may concurrently operate against a ConnectionPool instance. Connections acquired from the pool are subject to the threadsafety constraints described by the API documentation for Connection.

  • Creates a ConnectionPool.

    Declaration

    Swift

    public init(connectionPoolConfiguration: ConnectionPoolConfiguration,
                connectionConfiguration: ConnectionConfiguration,
                connectionDelegate: ConnectionDelegate? = nil)

    Parameters

    connectionPoolConfiguration

    the configuration for the ConnectionPool

    connectionConfiguration

    the configuration for Connection instances in the pool

    connectionDelegate

    an optional delegate for the Connection instances

  • The configuration of this ConnectionPool.

    The ConnectionPoolConfiguration is mutable. Configuration changes take effect for subsequent requests for connections.

    Declaration

    Swift

    public var connectionPoolConfiguration: ConnectionPoolConfiguration { get set }
  • The configuration of Connection instances in this ConnectionPool.

    Declaration

    Swift

    public let connectionConfiguration: ConnectionConfiguration
  • An optional delegate for Connection instances in this ConnectionPool.

    Declaration

    Swift

    public let connectionDelegate: ConnectionDelegate?
  • Requests a Connection from this ConnectionPool.

    This method is non-blocking: its completion handler is asynchronously executed when a connection is successfully allocated or an error occurs. ConnectionPoolConfiguration.dispatchQueue controls the DispatchQueue on which the completion handler is executed.

    If the request backlog is too large (ConnectionPoolConfiguration.maximumPendingRequests), the request will fail with PostgresError.tooManyRequestsForConnections.

    If a connection is available, it will be allocated to the request and passed to the completion handler. Otherwise, the request will join the backlog of pending requests. As connections become available, they are allocated to the pending requests in the order those requests were received.

    If a connection is not allocated to the request before it times out (ConnectionPoolConfiguration.pendingRequestTimeout), the request will fail with PostgresError.timedOutAcquiringConnection.

    When a connection is successfully allocated to the request, the completion handler (or any code it triggers) can use that connection to perform one or more SQL statements. When finished with the connection, call releaseConnection(_:) to release it back to this ConnectionPool. If releaseConnection(_:) is not called before the allocated connection times out (ConnectionPoolConfiguration.allocatedConnectionTimeout), the connection will be forcibly closed and removed from the ConnectionPool.

    Example:

    connectionPool.acquireConnection { result in
        do {
            let connection = try result.get()
            defer { connectionPool.releaseConnection(connection) }
    
            let statement = try connection.prepareStatement(text: ...)
            ...
        } catch {
            ...
        }
    }
    

    Declaration

    Swift

    public func acquireConnection(
        completionHandler: @escaping (Result<Connection, Error>) -> Void)

    Parameters

    completionHandler

    a completion handler, passed a value that either indicates success (with an associated Connection) or failure (with an associated Error)

  • Releases a Connection back to this ConnectionPool.

    Each Connection acquired by calling acquireConnection(completionHandler:) should be released exactly once. After invoking this method, do not further operate on the Connection instance.

    Declaration

    Swift

    public func releaseConnection(_ connection: Connection)

    Parameters

    connection

    the Connection to release

  • Requests a Connection from this ConnectionPool, automatically releasing it after executing the specified completion handler.

    This method operates identically to acquireConnection(completionHandler:), except that the acquired connection is automatically released after executing the completion handler.

    Do not call releaseConnection(_:) on the Connection passed to the completion handler.

    Example:

    connectionPool.withConnection { result in
        do {
            let connection = try result.get()
            let statement = try connection.prepareStatement(text: ...)
            ...
        } catch {
            ...
        }
    }
    

    Declaration

    Swift

    public func withConnection(completionHandler: @escaping (Result<Connection, Error>) -> Void)

    Parameters

    completionHandler

    a completion handler, passed a value that either indicates success (with an associated Connection) or failure (with an associated Error)

  • Gets performance metrics for this ConnectionPool.

    The returned metrics describe ConnectionPool performance for the period starting when the metrics were last reset (or when this ConnectionPool was initialized, if the metrics have never been reset) and ending at the current moment in time.

    Performance metrics can also be periodically logged. See ConnectionPoolConfiguration.metricsLoggingInterval.

    Declaration

    Swift

    @discardableResult
    public func computeMetrics(reset: Bool) -> ConnectionPoolMetrics

    Parameters

    reset

    whether to reset the metrics

    Return Value

    the metrics

  • Whether this ConnectionPool is closed.

    Declaration

    Swift

    public var isClosed: Bool { get }
  • Closes this ConnectionPool.

    Any pending requests for connections are canceled.

    If force is true, all Connection instances in this ConnectionPool are immediately forcibly closed.

    If force is false, only the unallocated Connection instances are immediately closed. The connections currently allocated to requests will be closed as those requests complete and the connections are released.

    Has no effect if this ConnectionPool is already closed.

    Declaration

    Swift

    public func close(force: Bool = false)

    Parameters

    force

    whether to immediately forcibly close Connection instances currently allocated to requests