From cdb6f1c3fe5223d7bc8623b73fc58745505ce190 Mon Sep 17 00:00:00 2001 From: forceoranj Date: Tue, 16 Nov 2021 17:32:58 +0100 Subject: [PATCH] Adds gSheet read cache --- src/gsheets/DBManager.ts | 64 +++++++++++++++++++++++++++ src/gsheets/accessors.ts | 12 ++--- src/gsheets/sequentialDBOperations.ts | 30 ------------- 3 files changed, 70 insertions(+), 36 deletions(-) create mode 100644 src/gsheets/DBManager.ts delete mode 100644 src/gsheets/sequentialDBOperations.ts diff --git a/src/gsheets/DBManager.ts b/src/gsheets/DBManager.ts new file mode 100644 index 0000000..03e0728 --- /dev/null +++ b/src/gsheets/DBManager.ts @@ -0,0 +1,64 @@ +const CACHE_RENEW_DELAY = 10000 + +export default function DBManager(): any { + type OperationType = "add" | "list" | "set" + + interface Operation { + task: () => Promise + type: OperationType + resolve: (value: OperationReturn) => void + reject: (reason: unknown) => void + } + + let cache: any + let cacheTime = 0 + + const operations: Operation[] = [] + + async function addDBOperation(type: OperationType, task: () => Promise) { + console.log(`New ${type} DB Operation in line.`) + return new Promise( + (resolve: (value: OperationReturn) => void, reject: (reason: unknown) => void) => { + operations.push({ task, type, resolve, reject }) + if (operations.length === 1) { + runOperation(operations[0]) + } + } + ) + } + + function runNextDBOperation(): void { + operations.shift() + console.log("DB Operation completed.") + if (operations[0]) { + runOperation(operations[0]) + } + } + + function runOperation(operation: Operation): void { + const { task, type, resolve, reject } = operation + if (type === "list") { + const now = +new Date() + if (now < cacheTime + CACHE_RENEW_DELAY) { + console.log("Using cache") + resolve(cache) + runNextDBOperation() + } else { + console.log("Refreshing cache") + task() + .then((val: OperationReturn) => { + cache = val + cacheTime = now + resolve(val) + }) + .catch(reject) + .finally(runNextDBOperation) + } + } else { + cacheTime = 0 + task().then(resolve).catch(reject).finally(runNextDBOperation) + } + } + + return addDBOperation +} diff --git a/src/gsheets/accessors.ts b/src/gsheets/accessors.ts index b2137b1..854f35b 100644 --- a/src/gsheets/accessors.ts +++ b/src/gsheets/accessors.ts @@ -3,9 +3,9 @@ import _ from "lodash" import { promises as fs } from "fs" import { GoogleSpreadsheet, GoogleSpreadsheetWorksheet } from "google-spreadsheet" -import sequentialDBOperations from "./sequentialDBOperations" +import DBManager from "./DBManager" -const addDBOperation = sequentialDBOperations() +const addDBOperation = DBManager() const SCOPES = ["https://www.googleapis.com/auth/spreadsheets"] const CRED_PATH = path.resolve(process.cwd(), "access/gsheets.json") @@ -17,7 +17,7 @@ export async function listGet( specimen: Element ): Promise { type StringifiedElement = Record - return addDBOperation(async () => { + return addDBOperation("list", async () => { const sheet = await getGSheet(sheetName) // Load sheet into an array of objects @@ -57,7 +57,7 @@ export async function setList( sheetName: string, elements: Element[] ): Promise { - return addDBOperation(async () => { + return addDBOperation("listSet", async () => { const sheet = await getGSheet(sheetName) // Load sheet into an array of objects @@ -117,7 +117,7 @@ export async function set( if (!element) { return undefined } - return addDBOperation(async () => { + return addDBOperation("set", async () => { const sheet = await getGSheet(sheetName) // Load sheet into an array of objects @@ -148,7 +148,7 @@ export async function add { + return addDBOperation("add", async () => { const sheet = await getGSheet(sheetName) // Load sheet into an array of objects diff --git a/src/gsheets/sequentialDBOperations.ts b/src/gsheets/sequentialDBOperations.ts deleted file mode 100644 index 62c3105..0000000 --- a/src/gsheets/sequentialDBOperations.ts +++ /dev/null @@ -1,30 +0,0 @@ -export default function sequentialDBOperations(): any { - interface Operation { - task: () => Promise - resolve: (value: OperationReturn) => void - reject: (reason: unknown) => void - } - - const operations: Operation[] = [] - - async function addDBOperation(task: () => Promise) { - return new Promise( - (resolve: (value: OperationReturn) => void, reject: (reason: unknown) => void) => { - operations.push({ task, resolve, reject }) - if (operations.length === 1) { - task().then(resolve).catch(reject).finally(runNextDBOperation) - } - } - ) - } - - function runNextDBOperation(): void { - operations.shift() - if (operations[0]) { - const { task, resolve, reject } = operations[0] - task().then(resolve).catch(reject).finally(runNextDBOperation) - } - } - - return addDBOperation -}