Skip to content

Commit

Permalink
fix: prevent reuse of broken connections in postgres pool
Browse files Browse the repository at this point in the history
  • Loading branch information
imnotjames committed Jun 23, 2021
1 parent 9300710 commit fb01d9d
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions src/driver/postgres/PostgresQueryRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
/**
* Special callback provided by a driver used to release a created connection.
*/
protected releaseCallback: Function;
protected releaseCallback?: (err: any) => void;

// -------------------------------------------------------------------------
// Constructor
Expand Down Expand Up @@ -84,7 +84,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
this.driver.connectedQueryRunners.push(this);
this.databaseConnection = connection;

const onErrorCallback = () => this.release();
const onErrorCallback = (err: Error) => this.releasePostgresConnection(err);
this.releaseCallback = () => {
this.databaseConnection.removeListener("error", onErrorCallback);
release();
Expand All @@ -99,7 +99,7 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
this.driver.connectedQueryRunners.push(this);
this.databaseConnection = connection;

const onErrorCallback = () => this.release();
const onErrorCallback = (err: Error) => this.releasePostgresConnection(err);
this.releaseCallback = () => {
this.databaseConnection.removeListener("error", onErrorCallback);
release();
Expand All @@ -114,22 +114,33 @@ export class PostgresQueryRunner extends BaseQueryRunner implements QueryRunner
}

/**
* Releases used database connection.
* You cannot use query runner methods once its released.
* Release a connection back to the pool, optionally specifying an Error to release with.
* Per pg-pool documentation this will prevent the pool from re-using the broken connection.
*/
release(): Promise<void> {
private async releasePostgresConnection(err?: Error) {
if (this.isReleased) {
return Promise.resolve();
return
}

this.isReleased = true;
if (this.releaseCallback)
this.releaseCallback();
if (this.releaseCallback) {
this.releaseCallback(err);
this.releaseCallback = undefined
}

const index = this.driver.connectedQueryRunners.indexOf(this);
if (index !== -1) this.driver.connectedQueryRunners.splice(index, 1);

return Promise.resolve();
if (index !== -1) {
this.driver.connectedQueryRunners.splice(index, 1);
}
}

/**
* Releases used database connection.
* You cannot use query runner methods once its released.
*/
release(): Promise<void> {
return this.releasePostgresConnection();
}

/**
Expand Down

0 comments on commit fb01d9d

Please sign in to comment.