diff --git a/src/databases/Postgres.ts b/src/databases/Postgres.ts index 6711897..1fa910d 100644 --- a/src/databases/Postgres.ts +++ b/src/databases/Postgres.ts @@ -33,6 +33,8 @@ export class Postgres implements IDatabase { private poolRead: Pool; private lastPoolReadFail = 0; + activePostgresRequests = 0; + constructor(private config: DatabaseConfig) {} async init(): Promise { @@ -108,6 +110,7 @@ export class Postgres implements IDatabase { tries++; try { + this.activePostgresRequests++; lastPool = this.getPool(type, options); 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))); const queryResult = await nextFulfilment(currentPromises); + this.activePostgresRequests--; switch (type) { case "get": { const value = queryResult.rows[0]; @@ -142,6 +146,7 @@ export class Postgres implements IDatabase { } } while (this.isReadQuery(type) && tries < maxTries()); + this.activePostgresRequests--; throw new Error(`prepare (postgres): ${type} ${query} failed after ${tries} tries`); } diff --git a/src/routes/getStatus.ts b/src/routes/getStatus.ts index 1f6dfcf..3f50fa1 100644 --- a/src/routes/getStatus.ts +++ b/src/routes/getStatus.ts @@ -2,8 +2,9 @@ import { db } from "../databases/databases"; import { Logger } from "../utils/logger"; import { Request, Response } from "express"; import os from "os"; -import redis from "../utils/redis"; +import redis, { getRedisActiveRequests } from "../utils/redis"; import { promiseOrTimeout } from "../utils/promise"; +import { Postgres } from "../databases/Postgres"; export async function getStatus(req: Request, res: Response): Promise { const startTime = Date.now(); @@ -42,7 +43,9 @@ export async function getStatus(req: Request, res: Response): Promise redisProcessTime, loadavg: os.loadavg().slice(1), // only return 5 & 15 minute load average 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); } catch (err) { diff --git a/src/utils/redis.ts b/src/utils/redis.ts index 6c13133..27b552c 100644 --- a/src/utils/redis.ts +++ b/src/utils/redis.ts @@ -27,6 +27,7 @@ let exportClient: RedisSB = { let lastClientFail = 0; let lastReadFail = 0; +let activeRequests = 0; if (config.redis?.enabled) { Logger.info("Connected to redis"); @@ -40,10 +41,13 @@ if (config.redis?.enabled) { const get = client.get.bind(client); const getRead = readClient?.get?.bind(readClient); exportClient.get = (key) => new Promise((resolve, reject) => { + activeRequests++; const timeout = config.redis.getTimeout ? setTimeout(() => reject(), config.redis.getTimeout) : null; const chosenGet = pickChoice(get, getRead); chosenGet(key).then((reply) => { if (timeout !== null) clearTimeout(timeout); + + activeRequests--; resolve(reply); }).catch((err) => { if (chosenGet === get) { @@ -52,6 +56,7 @@ if (config.redis?.enabled) { lastReadFail = Date.now(); } + activeRequests--; reject(err); }); }); @@ -91,4 +96,8 @@ function pickChoice(client: T, readClient: T): T { } } +export function getRedisActiveRequests(): number { + return activeRequests; +} + export default exportClient;