From 007214986e421621eb4ec858907e51ae083c1cf7 Mon Sep 17 00:00:00 2001 From: Jack Wink <57678801+mothershipper@users.noreply.github.com> Date: Sat, 6 Jun 2020 13:39:59 -0700 Subject: [PATCH] feat: add postgres connection timeout option (#6160) There was no documented way of setting a connection timeout for the postgres driver. We recently ran into an issue with our network that caused a container to hang indefinitely attempting to connect to postgres. We managed to resolve the issue by setting 'connectionTimeoutMillis' in the 'extra' field of our connection options. This approach does not appear to be documented anywhere. Seeing that MongoDB and MySQL drivers both support a connection timeout as part of the documented API, we felt it made sense to add a similar option to the Postgres driver and hopefully avoid some headaches down the road. This commit adds a 'connectTimeoutMS' option to the postgres driver that gets translated to the appropriate field for the pg library. It also updates the documentation to reflect this new option. Because the default behavior of the underlying pg library is to attempt to connect indefinitely, we didn't feel like it was a safe change to introduce a default timeout, even if that's more sane behavior. As mentioned earlier, both the MySQL and MongoDB drivers support a connection timeout option. MySQL uses 'connectTimeout' while MongoDB uses 'connectTimeoutMS'. We went with 'connectTimeoutMS' as to not introduce yet another name for a connection timeout, and because the 'MS' suffix makes it clearer what is expected. We hope a future PR may adjust the MySQL connection options to adopt the same name, but will leave that up to someone with a stronger opinion. --- docs/connection-options.md | 2 ++ src/driver/postgres/PostgresConnectionOptions.ts | 6 ++++++ src/driver/postgres/PostgresDriver.ts | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/connection-options.md b/docs/connection-options.md index 485b8d17fb..cd9915732f 100644 --- a/docs/connection-options.md +++ b/docs/connection-options.md @@ -173,6 +173,8 @@ See [SSL options](https://github.com/mysqljs/mysql#ssl-options). * `schema` - Schema name. Default is "public". +* `connectTimeoutMS` - The milliseconds before a timeout occurs during the initial connection to the postgres server. If `undefined`, or set to `0`, there is no timeout. Defaults to `undefined`. + * `ssl` - Object with ssl parameters. See [TLS/SSL](https://node-postgres.com/features/ssl). * `uuidExtension` - The Postgres extension to use when generating UUIDs. Defaults to `uuid-ossp`. Can be changed to `pgcrypto` if the `uuid-ossp` extension is unavailable. diff --git a/src/driver/postgres/PostgresConnectionOptions.ts b/src/driver/postgres/PostgresConnectionOptions.ts index aa70411217..18e65183b9 100644 --- a/src/driver/postgres/PostgresConnectionOptions.ts +++ b/src/driver/postgres/PostgresConnectionOptions.ts @@ -33,6 +33,12 @@ export interface PostgresConnectionOptions extends BaseConnectionOptions, Postgr }; + /** + * The milliseconds before a timeout occurs during the initial connection to the postgres + * server. If undefined, or set to 0, there is no timeout. Defaults to undefined. + */ + readonly connectTimeoutMS?: number; + /** * The Postgres extension to use to generate UUID columns. Defaults to uuid-ossp. * If pgcrypto is selected, TypeORM will use the gen_random_uuid() function from this extension. diff --git a/src/driver/postgres/PostgresDriver.ts b/src/driver/postgres/PostgresDriver.ts index a31755dd09..b45ac1c935 100644 --- a/src/driver/postgres/PostgresDriver.ts +++ b/src/driver/postgres/PostgresDriver.ts @@ -925,13 +925,15 @@ export class PostgresDriver implements Driver { credentials = Object.assign({}, credentials, DriverUtils.buildDriverOptions(credentials)); // todo: do it better way // build connection options for the driver + // See: https://github.com/brianc/node-postgres/tree/master/packages/pg-pool#create const connectionOptions = Object.assign({}, { host: credentials.host, user: credentials.username, password: credentials.password, database: credentials.database, port: credentials.port, - ssl: credentials.ssl + ssl: credentials.ssl, + connectionTimeoutMillis: options.connectTimeoutMS }, options.extra || {}); // create a connection pool