cache next and previous lots to speed up paging

deepsource-autofix-76c6eb20
Dan Gowans 2023-01-19 15:17:45 -05:00
parent fcdd8f950e
commit e1f766f712
11 changed files with 120 additions and 13 deletions

View File

@ -1,7 +1,7 @@
import * as configFunctions from '../../helpers/functions.config.js'; import * as configFunctions from '../../helpers/functions.config.js';
import { getNextLotId } from '../../helpers/lotOccupancyDB/getNextLotId.js'; import { getNextLotId } from '../../helpers/functions.lots.js';
export async function handler(request, response) { export async function handler(request, response) {
const lotId = request.params.lotId; const lotId = Number.parseInt(request.params.lotId, 10);
const nextLotId = await getNextLotId(lotId); const nextLotId = await getNextLotId(lotId);
if (!nextLotId) { if (!nextLotId) {
response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') + response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') +

View File

@ -2,13 +2,13 @@ import type { Request, Response } from 'express'
import * as configFunctions from '../../helpers/functions.config.js' import * as configFunctions from '../../helpers/functions.config.js'
import { getNextLotId } from '../../helpers/lotOccupancyDB/getNextLotId.js' import { getNextLotId } from '../../helpers/functions.lots.js'
export async function handler( export async function handler(
request: Request, request: Request,
response: Response response: Response
): Promise<void> { ): Promise<void> {
const lotId = request.params.lotId const lotId = Number.parseInt(request.params.lotId, 10)
const nextLotId = await getNextLotId(lotId) const nextLotId = await getNextLotId(lotId)

View File

@ -1,7 +1,7 @@
import * as configFunctions from '../../helpers/functions.config.js'; import * as configFunctions from '../../helpers/functions.config.js';
import { getPreviousLotId } from '../../helpers/lotOccupancyDB/getPreviousLotId.js'; import { getPreviousLotId } from '../../helpers/functions.lots.js';
export async function handler(request, response) { export async function handler(request, response) {
const lotId = request.params.lotId; const lotId = Number.parseInt(request.params.lotId, 10);
const previousLotId = await getPreviousLotId(lotId); const previousLotId = await getPreviousLotId(lotId);
if (!previousLotId) { if (!previousLotId) {
response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') + response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') +

View File

@ -2,13 +2,13 @@ import type { Request, Response } from 'express'
import * as configFunctions from '../../helpers/functions.config.js' import * as configFunctions from '../../helpers/functions.config.js'
import { getPreviousLotId } from '../../helpers/lotOccupancyDB/getPreviousLotId.js' import { getPreviousLotId } from '../../helpers/functions.lots.js'
export async function handler( export async function handler(
request: Request, request: Request,
response: Response response: Response
): Promise<void> { ): Promise<void> {
const lotId = request.params.lotId const lotId = Number.parseInt(request.params.lotId, 10)
const previousLotId = await getPreviousLotId(lotId) const previousLotId = await getPreviousLotId(lotId)

View File

@ -1,8 +1,9 @@
import * as configFunctions from '../../helpers/functions.config.js'; import * as configFunctions from '../../helpers/functions.config.js';
import { getNextLotId, getPreviousLotId } from '../../helpers/functions.lots.js';
import { getLot } from '../../helpers/lotOccupancyDB/getLot.js'; import { getLot } from '../../helpers/lotOccupancyDB/getLot.js';
export async function handler(request, response) { export async function handler(request, response) {
const lot = await getLot(request.params.lotId); const lot = await getLot(request.params.lotId);
if (!lot) { if (lot === undefined) {
response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') + response.redirect(configFunctions.getProperty('reverseProxy.urlPrefix') +
'/lots/?error=lotIdNotFound'); '/lots/?error=lotIdNotFound');
return; return;
@ -11,5 +12,9 @@ export async function handler(request, response) {
headTitle: lot.lotName, headTitle: lot.lotName,
lot lot
}); });
response.on('finish', () => {
void getNextLotId(lot.lotId);
void getPreviousLotId(lot.lotId);
});
} }
export default handler; export default handler;

View File

@ -1,6 +1,7 @@
import type { Request, Response } from 'express' import type { Request, Response } from 'express'
import * as configFunctions from '../../helpers/functions.config.js' import * as configFunctions from '../../helpers/functions.config.js'
import { getNextLotId, getPreviousLotId } from '../../helpers/functions.lots.js'
import { getLot } from '../../helpers/lotOccupancyDB/getLot.js' import { getLot } from '../../helpers/lotOccupancyDB/getLot.js'
@ -10,7 +11,7 @@ export async function handler(
): Promise<void> { ): Promise<void> {
const lot = await getLot(request.params.lotId) const lot = await getLot(request.params.lotId)
if (!lot) { if (lot === undefined) {
response.redirect( response.redirect(
configFunctions.getProperty('reverseProxy.urlPrefix') + configFunctions.getProperty('reverseProxy.urlPrefix') +
'/lots/?error=lotIdNotFound' '/lots/?error=lotIdNotFound'
@ -22,6 +23,11 @@ export async function handler(
headTitle: lot.lotName, headTitle: lot.lotName,
lot lot
}) })
response.on('finish', () => {
void getNextLotId(lot.lotId)
void getPreviousLotId(lot.lotId)
})
} }
export default handler export default handler

2
helpers/functions.lots.d.ts vendored 100644
View File

@ -0,0 +1,2 @@
export declare function getNextLotId(lotId: number): Promise<number | undefined>;
export declare function getPreviousLotId(lotId: number): Promise<number | undefined>;

View File

@ -0,0 +1,31 @@
import NodeCache from 'node-cache';
import getPreviousLotIdFromDatabase from './lotOccupancyDB/getPreviousLotId.js';
import getNextLotIdFromDatabase from './lotOccupancyDB/getNextLotId.js';
const previousLotIdCache = new NodeCache({
stdTTL: 2 * 60
});
const nextLotIdCache = new NodeCache({
stdTTL: 2 * 60
});
export async function getNextLotId(lotId) {
let nextLotId = nextLotIdCache.get(lotId);
if (nextLotId === undefined) {
nextLotId = await getNextLotIdFromDatabase(lotId);
if (nextLotId !== undefined) {
previousLotIdCache.set(nextLotId, lotId);
nextLotIdCache.set(lotId, nextLotId);
}
}
return nextLotId;
}
export async function getPreviousLotId(lotId) {
let previousLotId = previousLotIdCache.get(lotId);
if (previousLotId === undefined) {
previousLotId = await getPreviousLotIdFromDatabase(lotId);
if (previousLotId !== undefined) {
previousLotIdCache.set(lotId, previousLotId);
nextLotIdCache.set(previousLotId, lotId);
}
}
return previousLotId;
}

View File

@ -0,0 +1,44 @@
import NodeCache from 'node-cache'
import getPreviousLotIdFromDatabase from './lotOccupancyDB/getPreviousLotId.js'
import getNextLotIdFromDatabase from './lotOccupancyDB/getNextLotId.js'
const previousLotIdCache = new NodeCache({
stdTTL: 2 * 60 // two minutes
})
const nextLotIdCache = new NodeCache({
stdTTL: 2 * 60 // two minutes
})
export async function getNextLotId(lotId: number): Promise<number | undefined> {
let nextLotId: number | undefined = nextLotIdCache.get(lotId)
if (nextLotId === undefined) {
nextLotId = await getNextLotIdFromDatabase(lotId)
if (nextLotId !== undefined) {
previousLotIdCache.set(nextLotId, lotId)
nextLotIdCache.set(lotId, nextLotId)
}
}
return nextLotId
}
export async function getPreviousLotId(
lotId: number
): Promise<number | undefined> {
let previousLotId: number | undefined = previousLotIdCache.get(lotId)
if (previousLotId === undefined) {
previousLotId = await getPreviousLotIdFromDatabase(lotId)
if (previousLotId !== undefined) {
previousLotIdCache.set(lotId, previousLotId)
nextLotIdCache.set(previousLotId, lotId)
}
}
return previousLotId
}

24
package-lock.json generated
View File

@ -35,6 +35,7 @@
"http-errors": "^2.0.0", "http-errors": "^2.0.0",
"ical-generator": "^3.6.1", "ical-generator": "^3.6.1",
"leaflet": "^1.9.3", "leaflet": "^1.9.3",
"node-cache": "^5.1.2",
"papaparse": "^5.3.2", "papaparse": "^5.3.2",
"randomcolor": "^0.6.2", "randomcolor": "^0.6.2",
"session-file-store": "^1.5.0", "session-file-store": "^1.5.0",
@ -2915,7 +2916,6 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"dev": true,
"engines": { "engines": {
"node": ">=0.8" "node": ">=0.8"
} }
@ -8741,6 +8741,17 @@
"integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==",
"dev": true "dev": true
}, },
"node_modules/node-cache": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
"integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
"dependencies": {
"clone": "2.x"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/node-domexception": { "node_modules/node-domexception": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@ -14873,8 +14884,7 @@
"clone": { "clone": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
"dev": true
}, },
"clone-buffer": { "clone-buffer": {
"version": "1.0.0", "version": "1.0.0",
@ -19340,6 +19350,14 @@
"integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==",
"dev": true "dev": true
}, },
"node-cache": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
"integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
"requires": {
"clone": "2.x"
}
},
"node-domexception": { "node-domexception": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",

View File

@ -59,6 +59,7 @@
"http-errors": "^2.0.0", "http-errors": "^2.0.0",
"ical-generator": "^3.6.1", "ical-generator": "^3.6.1",
"leaflet": "^1.9.3", "leaflet": "^1.9.3",
"node-cache": "^5.1.2",
"papaparse": "^5.3.2", "papaparse": "^5.3.2",
"randomcolor": "^0.6.2", "randomcolor": "^0.6.2",
"session-file-store": "^1.5.0", "session-file-store": "^1.5.0",