sunrise-cms/helpers/functions.lots.ts

145 lines
3.5 KiB
TypeScript

/* eslint-disable @typescript-eslint/indent */
import cluster from 'node:cluster'
import NodeCache from 'node-cache'
import getPreviousLotIdFromDatabase from '../database/getPreviousLotId.js'
import getNextLotIdFromDatabase from '../database/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
}
const previousLotIdCache = new NodeCache(cacheOptions)
const nextLotIdCache = new NodeCache(cacheOptions)
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> {
let nextLotId: number | undefined = nextLotIdCache.get(lotId)
if (nextLotId === undefined) {
nextLotId = await getNextLotIdFromDatabase(lotId)
if (nextLotId !== undefined) {
cacheLotIds(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) {
cacheLotIds(previousLotId, lotId)
}
}
return previousLotId
}
export function clearNextPreviousLotIdCache(
lotId: number | -1,
relayMessage = true
): void {
if (lotId === undefined || lotId === -1) {
previousLotIdCache.flushAll()
nextLotIdCache.flushAll()
return
}
const previousLotId: number | undefined = previousLotIdCache.get(lotId)
if (previousLotId !== undefined) {
nextLotIdCache.del(previousLotId)
previousLotIdCache.del(lotId)
}
const nextLotId: number | undefined = nextLotIdCache.get(lotId)
if (nextLotId !== undefined) {
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
}
}
}
}
)