Skip to content

Explicit Resource Management for pg pool client#3661

Open
hyperair wants to merge 13 commits intobrianc:masterfrom
hyperair:disposable-pool-client
Open

Explicit Resource Management for pg pool client#3661
hyperair wants to merge 13 commits intobrianc:masterfrom
hyperair:disposable-pool-client

Conversation

@hyperair
Copy link
Copy Markdown

@hyperair hyperair commented Apr 27, 2026

Add support for Explicit Resource Management for pg.Pool clients.

This is implemented using [Symbol.dispose] instead of [Symbol.asyncDispose] because client.release() is a synchronous function, not async.

Additionally, add a second property client.destroyOnDispose so that Symbol.dispose supports calling client.release(true). This is useful for a usecase that changes connection parameters in a way that is troublesome to reset upon release to the pool, e.g.

const pool = new Pool({
    database: 'foo',
    user: 'foo',
    password: 'foo',
    port: 5432,

    statement_timeout: 10_000,
});

async function getSlowClient() {
    const client = await pool.connect();
    await client.query("SET statement_timeout = 0");
    client.destroyOnDispose = true;
}

async function performReallySlowQuery() {
    using client = await getSlowClient();

    client.query(`select pg_sleep_for('30 minutes')`);
}

Fixes: #3515

Note: This PR has been rebased on top of #3662, so there are some irrelevant commits until that PR is merged.

@hyperair hyperair force-pushed the disposable-pool-client branch 3 times, most recently from bac8c73 to 7d69534 Compare April 27, 2026 05:05
@hyperair
Copy link
Copy Markdown
Author

Hmm, looks like eslint needs to be upgraded before it'll parse the using test

@hyperair hyperair marked this pull request as draft April 27, 2026 13:10
- rootDir defaults have changed, so we need to specify it manually now
- baseUrl is no longer supported
- types no longer loads everything in @types by default, so we have to specify
  that we want node types
- Pin @types/node to 16.* because we support node16 and above
Fixes the following error:

    % yarn build
    yarn run v1.22.19
    $ tsc --build
    packages/pg-cloudflare/src/index.ts:156:29 - error TS2769: No overload matches this call.
      The last overload gave the following error.
        Argument of type 'ArrayBuffer | Uint8Array<ArrayBufferLike>' is not assignable to parameter of type 'WithImplicitCoercion<string> | { [Symbol.toPrimitive](hint: "string"): string; }'.
          Type 'ArrayBuffer' is not assignable to type 'WithImplicitCoercion<string> | { [Symbol.toPrimitive](hint: "string"): string; }'.

    156     const hex = Buffer.from(data).toString('hex')
                                    ~~~~

      node_modules/@types/node/buffer.buffer.d.ts:83:13
         83             from(
                        ~~~~~
         84                 str:
            ~~~~~~~~~~~~~~~~~~~~
        ...
         89                 encoding?: BufferEncoding,
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         90             ): Buffer<ArrayBuffer>;
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        The last overload is declared here.

    Found 1 error.

See microsoft/TypeScript#63447 for more info
Fixes the following typescript error:

    node_modules/typescript/lib/lib.esnext.intl.d.ts:26:135 - error TS2552: Cannot find name 'DateTimeRangeFormatPart'. Did you mean 'DateTimeFormatPart'?

    26         formatRangeToParts(startDate: FormattableTemporalObject | Date | number, endDate: FormattableTemporalObject | Date | number): DateTimeRangeFormatPart[];
`BufferReader.encoding` to `BufferEncoding` from `string` to match the new
signature of `Buffer.toString`.
When `Symbol.dispose` is defined, define a disposer function that simply calls
`this.release()`. This lets the `PoolClient` with the `using` syntax work with any
downstream-overridden `release` functions.

This makes `PoolClient` support Explicit Resource Management when the runtime
supports it.

Fixes: brianc#3515
Add a `destroyOnDispose` property on the client to signal that
`[Symbol.dispose]()` should call `client.release(true)` instead of
`client.release()`.
@hyperair hyperair force-pushed the disposable-pool-client branch from 0cb5f67 to 24caf46 Compare April 28, 2026 10:26
@hyperair hyperair marked this pull request as ready for review April 28, 2026 10:34
@hyperair hyperair requested a review from hjr3 as a code owner April 28, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Symbol.asyncDispose support

1 participant