async_postgres/pg_connection/lifecycle

Connection lifecycle: open, authenticate, fail over across hosts, close.

Contains:

  • Authentication helpers (enforceAuthAllowed, filterSaslByRequireAuth, selectScramMechanism) that the auth loop in connectToHost consumes.
  • connectToHost — the single-host bootstrap: socket → SSL → startup → auth loop → ParameterStatus/BackendKeyData → extension OID discovery.
  • connect — the public entry: multi-host failover, targetSessionAttrs handling, optional connectTimeout, top-level connect tracing.
  • orderedHosts — the host list to try, reordered per loadBalanceHosts (lbhRandom shuffles it once per connection).
  • close — idempotent teardown: stop background listen pump, send Terminate, drop transport handles.

Imports simple_query for checkSessionAttrs (failover probe). Re-exported through pg_connection.nim.

Procs

proc close(conn: PgConnection): Future[void] {....stackTrace: false,
    raises: [Exception, ValueError, LibraryError, SslError], tags: [RootEffect],
    forbids: [].}
Close the connection. Idempotent: safe to call multiple times.
proc connect(config: ConnConfig): Future[PgConnection] {.
    ...raises: [Exception, ValueError, PgConnectionError, CatchableError],
    tags: [RootEffect, WriteIOEffect, TimeEffect], forbids: [].}
Establish a new connection to a PostgreSQL server. Supports multi-host failover: tries each host in order, or in a random order when loadBalanceHosts == lbhRandom (libpq load_balance_hosts). Respects targetSessionAttrs to select the appropriate server type. connectTimeout is applied per host (libpq semantics): each host attempt gets its own budget, so the total wait may reach connectTimeout * hosts.
proc connect(dsn: string): Future[PgConnection] {....raises: [Exception,
    ValueError, PgConnectionError, CatchableError, PgError],
    tags: [RootEffect, WriteIOEffect, TimeEffect, ReadIOEffect], forbids: [].}
Shorthand for connect(parseDsn(dsn)).
proc connectToHost(config: ConnConfig; entry: HostEntry): Future[PgConnection] {.
    ...stackTrace: false, raises: [Exception, ValueError, CancelledError,
                                PgConnectionError, OSError, LibraryError,
                                SslError, CatchableError],
    tags: [RootEffect, WriteIOEffect, TimeEffect], forbids: [].}
Connect to a single PostgreSQL host. Internal helper for multi-host connect. Dials entry.hostaddr when given (bypassing name resolution), otherwise entry.host; SSL certificate verification always uses entry.host.
proc enforceAuthAllowed(authMethod: AuthMethod; allowed: set[AuthMethod];
                        offered: string = "") {....raises: [PgConnectionError],
    tags: [], forbids: [].}
proc filterSaslByRequireAuth(mechs: seq[string]; allowed: set[AuthMethod]): seq[
    string] {....raises: [], tags: [], forbids: [].}
Filter a server-offered SASL mechanism list by the client's requireAuth policy. An empty allowed set performs no filtering (matching libpq semantics when require_auth is unset).
proc orderedHosts(config: ConnConfig): seq[HostEntry] {.
    ...raises: [PgConnectionError], tags: [], forbids: [].}

getHosts, reordered per config.loadBalanceHosts. With lbhRandom (libpq load_balance_hosts=random) the configured host list is shuffled once per call, so a pool of connections spreads across hosts. With lbhDisable (default) the configured order is preserved. Only the multi-host list is reordered — multiple addresses behind a single host name are not shuffled (attemptHost dials the first resolved address).

The shuffle is seeded from the OS secure random source (std/sysrand) into a local std/random RNG, so it is safe under --threads:on, does not require the application to call randomize(), and keeps no module-level state.

proc selectScramMechanism(sslEnabled: bool; serverCertDer: openArray[byte];
                          saslMechanisms: seq[string]; mode: ChannelBindingMode): tuple[
    mechanism: string, cbType: string, cbData: seq[byte],
    cbSupportedButUnused: bool] {....raises: [PgConnectionError],
                                  tags: [RootEffect], forbids: [].}
Pick the SCRAM mechanism and channel-binding material for a SASL authentication attempt. Raises PgConnectionError when the server-offered mechanisms cannot satisfy mode. cbSupportedButUnused is true only when TLS is in use, plain SCRAM-SHA-256 was selected, and the server did not offer SCRAM-SHA-256-PLUS; the caller then emits a "y,," gs2 header so the server can detect a SCRAM-SHA-256-PLUS downgrade (libpq parity). When the server offered -PLUS but it could not be used (e.g. the certificate was unavailable), or for cbDisable, it stays false so a "n,," header is sent.