Add timeout for replica requests on non replica too

This commit is contained in:
Ajay
2022-07-22 20:00:38 -04:00
parent ad7080d801
commit 9764c01428
2 changed files with 20 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import { Client, Pool, types } from "pg";
import fs from "fs"; import fs from "fs";
import { CustomPostgresConfig, CustomPostgresReadOnlyConfig } from "../types/config.model"; import { CustomPostgresConfig, CustomPostgresReadOnlyConfig } from "../types/config.model";
import { promiseTimeout } from "../utils/promiseTimeout";
// return numeric (pg_type oid=1700) as float // return numeric (pg_type oid=1700) as float
types.setTypeParser(1700, function(val) { types.setTypeParser(1700, function(val) {
@@ -31,6 +32,7 @@ export class Postgres implements IDatabase {
private poolRead: Pool; private poolRead: Pool;
private lastPoolReadFail = 0; private lastPoolReadFail = 0;
private readTimeout = 400;
private maxTries = 3; private maxTries = 3;
@@ -109,7 +111,7 @@ export class Postgres implements IDatabase {
try { try {
lastPool = this.getPool(type, options); lastPool = this.getPool(type, options);
const queryResult = await lastPool.query({ text: query, values: params }); const queryResult = await promiseTimeout(lastPool.query({ text: query, values: params }), options.useReplica ? this.readTimeout : null);
switch (type) { switch (type) {
case "get": { case "get": {
@@ -136,11 +138,11 @@ export class Postgres implements IDatabase {
Logger.error(`prepare (postgres) try ${tries}: ${err}`); Logger.error(`prepare (postgres) try ${tries}: ${err}`);
} }
} while ((type === "get" || type === "all") && tries < this.maxTries); } while (this.isReadQuery(type) && tries < this.maxTries);
} }
private getPool(type: string, options: QueryOption): Pool { private getPool(type: string, options: QueryOption): Pool {
const readAvailable = this.poolRead && options.useReplica && (type === "get" || type === "all"); const readAvailable = this.poolRead && options.useReplica && this.isReadQuery(type);
const ignroreReadDueToFailure = this.lastPoolReadFail > Date.now() - 1000 * 30; const ignroreReadDueToFailure = this.lastPoolReadFail > Date.now() - 1000 * 30;
const readDueToFailure = this.lastPoolFail > Date.now() - 1000 * 30; const readDueToFailure = this.lastPoolFail > Date.now() - 1000 * 30;
if (readAvailable && !ignroreReadDueToFailure && (options.forceReplica || readDueToFailure || if (readAvailable && !ignroreReadDueToFailure && (options.forceReplica || readDueToFailure ||
@@ -151,6 +153,10 @@ export class Postgres implements IDatabase {
} }
} }
private isReadQuery(type: string): boolean {
return type === "get" || type === "all";
}
private async createDB() { private async createDB() {
const client = new Client({ const client = new Client({
...this.config.postgres, ...this.config.postgres,

View File

@@ -0,0 +1,11 @@
export function promiseTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {
return new Promise((resolve, reject) => {
if (timeout) {
setTimeout(() => {
reject(new Error("Promise timed out"));
}, timeout);
}
promise.then(resolve, reject);
});
}