Count active postgres and redis requests

This commit is contained in:
Ajay
2022-10-26 01:31:29 -04:00
parent 0ced78d798
commit 94eb37cb1c
3 changed files with 19 additions and 2 deletions

View File

@@ -33,6 +33,8 @@ export class Postgres implements IDatabase {
private poolRead: Pool; private poolRead: Pool;
private lastPoolReadFail = 0; private lastPoolReadFail = 0;
activePostgresRequests = 0;
constructor(private config: DatabaseConfig) {} constructor(private config: DatabaseConfig) {}
async init(): Promise<void> { async init(): Promise<void> {
@@ -108,6 +110,7 @@ export class Postgres implements IDatabase {
tries++; tries++;
try { try {
this.activePostgresRequests++;
lastPool = this.getPool(type, options); lastPool = this.getPool(type, options);
pendingQueries.push(savePromiseState(lastPool.query({ text: query, values: params }))); pendingQueries.push(savePromiseState(lastPool.query({ text: query, values: params })));
@@ -115,6 +118,7 @@ export class Postgres implements IDatabase {
if (options.useReplica && maxTries() - tries > 1) currentPromises.push(savePromiseState(timeoutPomise(this.config.postgresReadOnly.readTimeout))); if (options.useReplica && maxTries() - tries > 1) currentPromises.push(savePromiseState(timeoutPomise(this.config.postgresReadOnly.readTimeout)));
const queryResult = await nextFulfilment(currentPromises); const queryResult = await nextFulfilment(currentPromises);
this.activePostgresRequests--;
switch (type) { switch (type) {
case "get": { case "get": {
const value = queryResult.rows[0]; const value = queryResult.rows[0];
@@ -142,6 +146,7 @@ export class Postgres implements IDatabase {
} }
} while (this.isReadQuery(type) && tries < maxTries()); } while (this.isReadQuery(type) && tries < maxTries());
this.activePostgresRequests--;
throw new Error(`prepare (postgres): ${type} ${query} failed after ${tries} tries`); throw new Error(`prepare (postgres): ${type} ${query} failed after ${tries} tries`);
} }

View File

@@ -2,8 +2,9 @@ import { db } from "../databases/databases";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { Request, Response } from "express"; import { Request, Response } from "express";
import os from "os"; import os from "os";
import redis from "../utils/redis"; import redis, { getRedisActiveRequests } from "../utils/redis";
import { promiseOrTimeout } from "../utils/promise"; import { promiseOrTimeout } from "../utils/promise";
import { Postgres } from "../databases/Postgres";
export async function getStatus(req: Request, res: Response): Promise<Response> { export async function getStatus(req: Request, res: Response): Promise<Response> {
const startTime = Date.now(); const startTime = Date.now();
@@ -42,7 +43,9 @@ export async function getStatus(req: Request, res: Response): Promise<Response>
redisProcessTime, redisProcessTime,
loadavg: os.loadavg().slice(1), // only return 5 & 15 minute load average loadavg: os.loadavg().slice(1), // only return 5 & 15 minute load average
statusRequests, statusRequests,
hostname: os.hostname() hostname: os.hostname(),
activePostgresRequests: (db as Postgres)?.activePostgresRequests,
activeRedisRequests: getRedisActiveRequests(),
}; };
return value ? res.send(JSON.stringify(statusValues[value])) : res.send(statusValues); return value ? res.send(JSON.stringify(statusValues[value])) : res.send(statusValues);
} catch (err) { } catch (err) {

View File

@@ -27,6 +27,7 @@ let exportClient: RedisSB = {
let lastClientFail = 0; let lastClientFail = 0;
let lastReadFail = 0; let lastReadFail = 0;
let activeRequests = 0;
if (config.redis?.enabled) { if (config.redis?.enabled) {
Logger.info("Connected to redis"); Logger.info("Connected to redis");
@@ -40,10 +41,13 @@ if (config.redis?.enabled) {
const get = client.get.bind(client); const get = client.get.bind(client);
const getRead = readClient?.get?.bind(readClient); const getRead = readClient?.get?.bind(readClient);
exportClient.get = (key) => new Promise((resolve, reject) => { exportClient.get = (key) => new Promise((resolve, reject) => {
activeRequests++;
const timeout = config.redis.getTimeout ? setTimeout(() => reject(), config.redis.getTimeout) : null; const timeout = config.redis.getTimeout ? setTimeout(() => reject(), config.redis.getTimeout) : null;
const chosenGet = pickChoice(get, getRead); const chosenGet = pickChoice(get, getRead);
chosenGet(key).then((reply) => { chosenGet(key).then((reply) => {
if (timeout !== null) clearTimeout(timeout); if (timeout !== null) clearTimeout(timeout);
activeRequests--;
resolve(reply); resolve(reply);
}).catch((err) => { }).catch((err) => {
if (chosenGet === get) { if (chosenGet === get) {
@@ -52,6 +56,7 @@ if (config.redis?.enabled) {
lastReadFail = Date.now(); lastReadFail = Date.now();
} }
activeRequests--;
reject(err); reject(err);
}); });
}); });
@@ -91,4 +96,8 @@ function pickChoice<T>(client: T, readClient: T): T {
} }
} }
export function getRedisActiveRequests(): number {
return activeRequests;
}
export default exportClient; export default exportClient;