From 87e38c8bc4462d8cb60264ac65e1a8445fe138cb Mon Sep 17 00:00:00 2001 From: Ajay Date: Sun, 20 Nov 2022 00:47:41 -0500 Subject: [PATCH] Show total stats if not under high load --- src/config.ts | 3 ++- src/databases/IDatabase.ts | 2 ++ src/databases/Mysql.ts | 4 ++++ src/databases/Postgres.ts | 4 ++++ src/databases/Sqlite.ts | 4 ++++ src/routes/getTotalStats.ts | 33 +++++++++++++++++++++++++++++---- src/types/config.model.ts | 1 + 7 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/config.ts b/src/config.ts index b6935d9..cb0bf34 100644 --- a/src/config.ts +++ b/src/config.ts @@ -78,7 +78,8 @@ addDefaults(config, { idleTimeoutMillis: 10000, maxTries: 3, maxActiveRequests: 0, - timeout: 60000 + timeout: 60000, + highLoadThreshold: 10 }, postgresReadOnly: { enabled: false, diff --git a/src/databases/IDatabase.ts b/src/databases/IDatabase.ts index 9cc82d4..717c700 100644 --- a/src/databases/IDatabase.ts +++ b/src/databases/IDatabase.ts @@ -7,6 +7,8 @@ export interface IDatabase { init(): Promise; prepare(type: QueryType, query: string, params?: any[], options?: QueryOption): Promise; + + highLoad(): boolean; } export type QueryType = "get" | "all" | "run"; \ No newline at end of file diff --git a/src/databases/Mysql.ts b/src/databases/Mysql.ts index d15b692..a68a12c 100644 --- a/src/databases/Mysql.ts +++ b/src/databases/Mysql.ts @@ -32,4 +32,8 @@ export class Mysql implements IDatabase { } } + highLoad() { + return false; + } + } diff --git a/src/databases/Postgres.ts b/src/databases/Postgres.ts index a6dcceb..7f65c9f 100644 --- a/src/databases/Postgres.ts +++ b/src/databases/Postgres.ts @@ -235,4 +235,8 @@ export class Postgres implements IDatabase { return result; } + + highLoad() { + return this.activePostgresRequests > this.config.postgres.highLoadThreshold; + } } diff --git a/src/databases/Sqlite.ts b/src/databases/Sqlite.ts index f5dd371..ac03753 100644 --- a/src/databases/Sqlite.ts +++ b/src/databases/Sqlite.ts @@ -95,6 +95,10 @@ export class Sqlite implements IDatabase { private static processUpgradeQuery(query: string): string { return query.replace(/^.*--!sqlite-ignore/gm, ""); } + + highLoad() { + return false; + } } export interface SqliteConfig { diff --git a/src/routes/getTotalStats.ts b/src/routes/getTotalStats.ts index e001d5d..187a59d 100644 --- a/src/routes/getTotalStats.ts +++ b/src/routes/getTotalStats.ts @@ -12,13 +12,26 @@ let firefoxUsersCache = 0; let apiUsersCache = 0; let lastUserCountCheck = 0; +interface DBStatsData { + userCount: number, + viewCount: number, + totalSubmissions: number, + minutesSaved: number +} + +let lastFetch: DBStatsData = { + userCount: 0, + viewCount: 0, + totalSubmissions: 0, + minutesSaved: 0 +}; + updateExtensionUsers(); export async function getTotalStats(req: Request, res: Response): Promise { - const userCountQuery = `(SELECT COUNT(*) FROM (SELECT DISTINCT "userID" from "sponsorTimes") t) "userCount",`; - const row = await db.prepare("get", `SELECT ${req.query.countContributingUsers ? userCountQuery : ""} COUNT(*) as "totalSubmissions", - SUM("views") as "viewCount", SUM(("endTime" - "startTime") / 60 * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "shadowHidden" != 1 AND "votes" >= 0 AND "actionType" != 'chapter'`, []); + const row = await getStats(!!req.query.countContributingUsers); + lastFetch = row; if (row !== undefined) { const extensionUsers = chromeUsersCache + firefoxUsersCache; @@ -43,6 +56,18 @@ export async function getTotalStats(req: Request, res: Response): Promise } } +function getStats(countContributingUsers: boolean): Promise { + if (db.highLoad()) { + return Promise.resolve(lastFetch); + } else { + const userCountQuery = `(SELECT COUNT(*) FROM (SELECT DISTINCT "userID" from "sponsorTimes") t) "userCount",`; + + return db.prepare("get", `SELECT ${countContributingUsers ? userCountQuery : ""} COUNT(*) as "totalSubmissions", + SUM("views") as "viewCount", SUM(("endTime" - "startTime") / 60 * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "shadowHidden" != 1 AND "votes" >= 0 AND "actionType" != 'chapter'`, []); + } +} + + function updateExtensionUsers() { if (config.userCounterURL) { axios.get(`${config.userCounterURL}/api/v1/userCount`) @@ -68,7 +93,7 @@ function updateExtensionUsers() { const userDownloadsStartIndex = body.indexOf(matchingString); if (userDownloadsStartIndex >= 0) { const closingQuoteIndex = body.indexOf('"', userDownloadsStartIndex + matchingStringLen); - const userDownloadsStr = body.substr(userDownloadsStartIndex + matchingStringLen, closingQuoteIndex - userDownloadsStartIndex).replace(",","").replace(".",""); + const userDownloadsStr = body.substr(userDownloadsStartIndex + matchingStringLen, closingQuoteIndex - userDownloadsStartIndex).replace(",", "").replace(".", ""); chromeUsersCache = parseInt(userDownloadsStr); } else { diff --git a/src/types/config.model.ts b/src/types/config.model.ts index 2fa6106..4adaa51 100644 --- a/src/types/config.model.ts +++ b/src/types/config.model.ts @@ -25,6 +25,7 @@ export interface CustomPostgresConfig extends PoolConfig { export interface CustomWritePostgresConfig extends CustomPostgresConfig { maxActiveRequests: number; timeout: number; + highLoadThreshold: number; } export interface CustomPostgresReadOnlyConfig extends CustomPostgresConfig {