clear lot cache messaging

deepsource-autofix-76c6eb20
Dan Gowans 2023-03-27 11:03:43 -04:00
parent e7b4753123
commit 18f5dc7103
11 changed files with 184 additions and 31 deletions

View File

@ -25,7 +25,6 @@ for (let index = 0; index < processCount; index += 1) {
activeWorkers.set(worker.process.pid, worker);
}
cluster.on('message', (worker, message) => {
if (message?.messageType === 'clearCache') {
for (const [pid, worker] of activeWorkers.entries()) {
if (worker === undefined || pid === message.pid) {
continue;
@ -33,7 +32,6 @@ cluster.on('message', (worker, message) => {
debug('Relaying message to workers');
worker.send(message);
}
}
});
cluster.on('exit', (worker, code, signal) => {
debug(`Worker ${worker.process.pid.toString()} has been killed`);

View File

@ -45,7 +45,6 @@ for (let index = 0; index < processCount; index += 1) {
}
cluster.on('message', (worker, message: WorkerMessage) => {
if (message?.messageType === 'clearCache') {
for (const [pid, worker] of activeWorkers.entries()) {
if (worker === undefined || pid === message.pid) {
continue
@ -54,7 +53,6 @@ cluster.on('message', (worker, message: WorkerMessage) => {
debug('Relaying message to workers')
worker.send(message)
}
}
})
cluster.on('exit', (worker, code, signal) => {

View File

@ -18,7 +18,7 @@ import { getWorkOrderTypes as getWorkOrderTypesFromDatabase } from './lotOccupan
import { getWorkOrderMilestoneTypes as getWorkOrderMilestoneTypesFromDatabase } from './lotOccupancyDB/getWorkOrderMilestoneTypes.js'
import type * as recordTypes from '../types/recordTypes'
import type { WorkerMessage } from '../types/applicationTypes'
import type { ClearCacheWorkerMessage } from '../types/applicationTypes'
import Debug from 'debug'
const debug = Debug(`lot-occupancy-system:functions.cache:${process.pid}`)
@ -343,7 +343,7 @@ export function clearCacheByTableName(
try {
if (relayMessage && cluster.isWorker) {
const workerMessage: WorkerMessage = {
const workerMessage: ClearCacheWorkerMessage = {
messageType: 'clearCache',
tableName,
timeMillis: Date.now(),
@ -357,7 +357,7 @@ export function clearCacheByTableName(
} catch {}
}
process.on('message', (message: WorkerMessage) => {
process.on('message', (message: ClearCacheWorkerMessage) => {
if (message.messageType === 'clearCache' && message.pid !== process.pid) {
debug(`Clearing cache: ${message.tableName}`)
clearCacheByTableName(message.tableName, false)

View File

@ -1,3 +1,3 @@
export declare function getNextLotId(lotId: number): Promise<number | undefined>;
export declare function getPreviousLotId(lotId: number): Promise<number | undefined>;
export declare function clearNextPreviousLotIdCache(lotId?: number): void;
export declare function clearNextPreviousLotIdCache(lotId: number | -1, relayMessage?: boolean): void;

View File

@ -1,15 +1,32 @@
import cluster from 'node:cluster';
import NodeCache from 'node-cache';
import getPreviousLotIdFromDatabase from './lotOccupancyDB/getPreviousLotId.js';
import getNextLotIdFromDatabase from './lotOccupancyDB/getNextLotId.js';
import Debug from 'debug';
const debug = Debug(`lot-occupancy-system:functions.lots:${process.pid}`);
const cacheOptions = {
stdTTL: 2 * 60,
useClones: false
};
const previousLotIdCache = new NodeCache(cacheOptions);
const nextLotIdCache = new NodeCache(cacheOptions);
function cacheLotIds(lotId, nextLotId) {
function cacheLotIds(lotId, nextLotId, relayMessage = true) {
previousLotIdCache.set(nextLotId, lotId);
nextLotIdCache.set(lotId, nextLotId);
try {
if (relayMessage && cluster.isWorker) {
const workerMessage = {
messageType: 'cacheLotIds',
lotId,
nextLotId,
timeMillis: Date.now(),
pid: process.pid
};
debug(`Sending cache lot ids from worker: (${lotId}, ${nextLotId})`);
process.send(workerMessage);
}
}
catch { }
}
export async function getNextLotId(lotId) {
let nextLotId = nextLotIdCache.get(lotId);
@ -31,8 +48,8 @@ export async function getPreviousLotId(lotId) {
}
return previousLotId;
}
export function clearNextPreviousLotIdCache(lotId) {
if (lotId === undefined) {
export function clearNextPreviousLotIdCache(lotId, relayMessage = true) {
if (lotId === undefined || lotId === -1) {
previousLotIdCache.flushAll();
nextLotIdCache.flushAll();
return;
@ -47,4 +64,33 @@ export function clearNextPreviousLotIdCache(lotId) {
previousLotIdCache.del(nextLotId);
nextLotIdCache.del(lotId);
}
try {
if (relayMessage && cluster.isWorker) {
const workerMessage = {
messageType: 'clearNextPreviousLotIdCache',
lotId,
timeMillis: Date.now(),
pid: process.pid
};
debug(`Sending clear next/previous lot cache from worker: ${lotId}`);
process.send(workerMessage);
}
}
catch { }
}
process.on('message', (message) => {
if (message.pid !== process.pid) {
switch (message.messageType) {
case 'cacheLotIds': {
debug(`Caching lot ids: (${message.lotId}, ${message.nextLotId})`);
cacheLotIds(message.lotId, message.nextLotId, false);
break;
}
case 'clearNextPreviousLotIdCache': {
debug(`Clearing next/previous lot cache: ${message.lotId}`);
clearNextPreviousLotIdCache(message.lotId, false);
break;
}
}
}
});

View File

@ -1,8 +1,18 @@
import cluster from 'node:cluster'
import NodeCache from 'node-cache'
import getPreviousLotIdFromDatabase from './lotOccupancyDB/getPreviousLotId.js'
import getNextLotIdFromDatabase from './lotOccupancyDB/getNextLotId.js'
import type {
CacheLotIdsWorkerMessage,
ClearNextPreviousLotIdsCacheWorkerMessage
} from '../types/applicationTypes.js'
import Debug from 'debug'
const debug = Debug(`lot-occupancy-system:functions.lots:${process.pid}`)
const cacheOptions: NodeCache.Options = {
stdTTL: 2 * 60, // two minutes
useClones: false
@ -12,9 +22,29 @@ const previousLotIdCache = new NodeCache(cacheOptions)
const nextLotIdCache = new NodeCache(cacheOptions)
function cacheLotIds(lotId: number, nextLotId: number): void {
function cacheLotIds(
lotId: number,
nextLotId: number,
relayMessage = true
): void {
previousLotIdCache.set(nextLotId, lotId)
nextLotIdCache.set(lotId, nextLotId)
try {
if (relayMessage && cluster.isWorker) {
const workerMessage: CacheLotIdsWorkerMessage = {
messageType: 'cacheLotIds',
lotId,
nextLotId,
timeMillis: Date.now(),
pid: process.pid
}
debug(`Sending cache lot ids from worker: (${lotId}, ${nextLotId})`)
process.send!(workerMessage)
}
} catch {}
}
export async function getNextLotId(lotId: number): Promise<number | undefined> {
@ -47,8 +77,11 @@ export async function getPreviousLotId(
return previousLotId
}
export function clearNextPreviousLotIdCache(lotId?: number): void {
if (lotId === undefined) {
export function clearNextPreviousLotIdCache(
lotId: number | -1,
relayMessage = true
): void {
if (lotId === undefined || lotId === -1) {
previousLotIdCache.flushAll()
nextLotIdCache.flushAll()
return
@ -67,4 +100,43 @@ export function clearNextPreviousLotIdCache(lotId?: number): void {
previousLotIdCache.del(nextLotId)
nextLotIdCache.del(lotId)
}
try {
if (relayMessage && cluster.isWorker) {
const workerMessage: ClearNextPreviousLotIdsCacheWorkerMessage = {
messageType: 'clearNextPreviousLotIdCache',
lotId,
timeMillis: Date.now(),
pid: process.pid
}
debug(`Sending clear next/previous lot cache from worker: ${lotId}`)
process.send!(workerMessage)
}
} catch {}
}
process.on(
'message',
(
message:
| ClearNextPreviousLotIdsCacheWorkerMessage
| CacheLotIdsWorkerMessage
) => {
if (message.pid !== process.pid) {
switch (message.messageType) {
case 'cacheLotIds': {
debug(`Caching lot ids: (${message.lotId}, ${message.nextLotId})`)
cacheLotIds(message.lotId, message.nextLotId, false)
break
}
case 'clearNextPreviousLotIdCache': {
debug(`Clearing next/previous lot cache: ${message.lotId}`)
clearNextPreviousLotIdCache(message.lotId, false)
break
}
}
}
}
)

View File

@ -1,6 +1,7 @@
import { acquireConnection } from './pool.js';
import { addOrUpdateLotField } from './addOrUpdateLotField.js';
import { deleteLotField } from './deleteLotField.js';
import { clearNextPreviousLotIdCache } from '../functions.lots.js';
export async function updateLot(lotForm, requestSession) {
const database = await acquireConnection();
const rightNowMillis = Date.now();
@ -32,6 +33,9 @@ export async function updateLot(lotForm, requestSession) {
}
}
database.release();
clearNextPreviousLotIdCache(typeof lotForm.lotId === 'number'
? lotForm.lotId
: Number.parseInt(lotForm.lotId, 10));
return result.changes > 0;
}
export async function updateLotStatus(lotId, lotStatusId, requestSession) {

View File

@ -5,6 +5,7 @@ import { addOrUpdateLotField } from './addOrUpdateLotField.js'
import { deleteLotField } from './deleteLotField.js'
import type * as recordTypes from '../../types/recordTypes'
import { clearNextPreviousLotIdCache } from '../functions.lots.js'
interface UpdateLotForm {
lotId: string | number
@ -87,6 +88,12 @@ export async function updateLot(
database.release()
clearNextPreviousLotIdCache(
typeof lotForm.lotId === 'number'
? lotForm.lotId
: Number.parseInt(lotForm.lotId, 10)
)
return result.changes > 0
}

View File

@ -10,8 +10,8 @@
"scripts": {
"start": "cross-env NODE_ENV=production node ./bin/www.js",
"dev:test": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:*,dynamics-gp:* TEST_DATABASES=true nodemon --inspect ./bin/www.js",
"dev:test:process": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon ./bin/wwwProcess.js",
"dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon ./bin/www.js",
"dev:test:process": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* TEST_DATABASES=true nodemon --inspect ./bin/wwwProcess.js",
"dev:live": "cross-env NODE_ENV=dev DEBUG=lot-occupancy-system:* nodemon --inspect ./bin/www.js",
"cy:open": "cypress open --config-file cypress.config.js",
"cy:run": "cypress run --config-file cypress.config.js",
"cy:run:firefox": "cypress run --config-file cypress.config.js --browser firefox",

View File

@ -1,6 +1,18 @@
export interface WorkerMessage {
messageType: 'clearCache';
tableName: string;
messageType: string;
timeMillis: number;
pid: number;
}
export interface ClearCacheWorkerMessage extends WorkerMessage {
messageType: 'clearCache';
tableName: string;
}
export interface CacheLotIdsWorkerMessage extends WorkerMessage {
messageType: 'cacheLotIds';
lotId: number;
nextLotId: number;
}
export interface ClearNextPreviousLotIdsCacheWorkerMessage extends WorkerMessage {
messageType: 'clearNextPreviousLotIdCache';
lotId: number;
}

View File

@ -1,6 +1,22 @@
export interface WorkerMessage {
messageType: 'clearCache'
tableName: string
messageType: string
timeMillis: number
pid: number
}
export interface ClearCacheWorkerMessage extends WorkerMessage {
messageType: 'clearCache'
tableName: string
}
export interface CacheLotIdsWorkerMessage extends WorkerMessage {
messageType: 'cacheLotIds'
lotId: number
nextLotId: number
}
export interface ClearNextPreviousLotIdsCacheWorkerMessage
extends WorkerMessage {
messageType: 'clearNextPreviousLotIdCache'
lotId: number
}