From 672501d9ed348b002f1c570d3fe09fa935c96b5e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 18 Apr 2023 14:21:15 +0800 Subject: [PATCH] feat: revise cache logic --- packages/nocodb-nest/src/cache/CacheMgr.ts | 8 +++- packages/nocodb-nest/src/cache/NocoCache.ts | 11 +++++- .../nocodb-nest/src/cache/RedisCacheMgr.ts | 36 ++++++++++++++---- .../src/cache/RedisMockCacheMgr.ts | 38 ++++++++++++++----- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/packages/nocodb-nest/src/cache/CacheMgr.ts b/packages/nocodb-nest/src/cache/CacheMgr.ts index 593a601d5f..0241f1c66b 100644 --- a/packages/nocodb-nest/src/cache/CacheMgr.ts +++ b/packages/nocodb-nest/src/cache/CacheMgr.ts @@ -4,7 +4,13 @@ export default abstract class CacheMgr { public abstract del(key: string): Promise; public abstract getAll(pattern: string): Promise; public abstract delAll(scope: string, pattern: string): Promise; - public abstract getList(scope: string, list: string[]): Promise; + public abstract getList( + scope: string, + list: string[], + ): Promise<{ + list: any[]; + isNoneList: boolean; + }>; public abstract setList( scope: string, subListKeys: string[], diff --git a/packages/nocodb-nest/src/cache/NocoCache.ts b/packages/nocodb-nest/src/cache/NocoCache.ts index 87d12a1ade..7f1cf18edf 100644 --- a/packages/nocodb-nest/src/cache/NocoCache.ts +++ b/packages/nocodb-nest/src/cache/NocoCache.ts @@ -56,8 +56,15 @@ export default class NocoCache { public static async getList( scope: string, subKeys: string[], - ): Promise { - if (this.cacheDisabled) return Promise.resolve([]); + ): Promise<{ + list: any[]; + isNoneList: boolean; + }> { + if (this.cacheDisabled) + return Promise.resolve({ + list: [], + isNoneList: false, + }); return this.client.getList(scope, subKeys); } diff --git a/packages/nocodb-nest/src/cache/RedisCacheMgr.ts b/packages/nocodb-nest/src/cache/RedisCacheMgr.ts index 489413c448..04f2aca34d 100644 --- a/packages/nocodb-nest/src/cache/RedisCacheMgr.ts +++ b/packages/nocodb-nest/src/cache/RedisCacheMgr.ts @@ -114,7 +114,13 @@ export default class RedisCacheMgr extends CacheMgr { ); } - async getList(scope: string, subKeys: string[]): Promise { + async getList( + scope: string, + subKeys: string[], + ): Promise<{ + list: any[]; + isNoneList: boolean; + }> { // remove null from arrays subKeys = subKeys.filter((k) => k); // e.g. key = nc:::::list @@ -125,9 +131,21 @@ export default class RedisCacheMgr extends CacheMgr { // e.g. arr = ["nc:::", "nc:::"] const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; log(`RedisCacheMgr::getList: getting list with key ${key}`); - return Promise.all( - arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)), - ); + const isNoneList = arr.length && arr[0] === 'NONE'; + + if (isNoneList) { + return Promise.resolve({ + list: [], + isNoneList, + }); + } + + return { + list: await Promise.all( + arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)), + ), + isNoneList, + }; } async setList( @@ -144,8 +162,8 @@ export default class RedisCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; if (!list.length) { - log(`RedisCacheMgr::setList: List is empty for ${listKey}. Skipping ...`); - return Promise.resolve(true); + // Set NONE here so that it won't hit the DB on each page load + return this.set(listKey, ['NONE']); } // fetch existing list const listOfGetKeys = @@ -225,7 +243,11 @@ export default class RedisCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; log(`RedisCacheMgr::appendToList: append key ${key} to ${listKey}`); - const list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + if (list.length && list[0] === 'NONE') { + list = []; + await this.del(listKey); + } list.push(key); return this.set(listKey, list); } diff --git a/packages/nocodb-nest/src/cache/RedisMockCacheMgr.ts b/packages/nocodb-nest/src/cache/RedisMockCacheMgr.ts index 430fb6122e..c4249ae484 100644 --- a/packages/nocodb-nest/src/cache/RedisMockCacheMgr.ts +++ b/packages/nocodb-nest/src/cache/RedisMockCacheMgr.ts @@ -114,7 +114,13 @@ export default class RedisMockCacheMgr extends CacheMgr { ); } - async getList(scope: string, subKeys: string[]): Promise { + async getList( + scope: string, + subKeys: string[], + ): Promise<{ + list: any[]; + isNoneList: boolean; + }> { // remove null from arrays subKeys = subKeys.filter((k) => k); // e.g. key = nc:::::list @@ -125,9 +131,21 @@ export default class RedisMockCacheMgr extends CacheMgr { // e.g. arr = ["nc:::", "nc:::"] const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; log(`RedisMockCacheMgr::getList: getting list with key ${key}`); - return Promise.all( - arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)), - ); + const isNoneList = arr.length && arr[0] === 'NONE'; + + if (isNoneList) { + return Promise.resolve({ + list: [], + isNoneList, + }); + } + + return { + list: await Promise.all( + arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT)), + ), + isNoneList, + }; } async setList( @@ -144,10 +162,8 @@ export default class RedisMockCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; if (!list.length) { - log( - `RedisMockCacheMgr::setList: List is empty for ${listKey}. Skipping ...`, - ); - return Promise.resolve(true); + // Set NONE here so that it won't hit the DB on each page load + return this.set(listKey, ['NONE']); } // fetch existing list const listOfGetKeys = @@ -227,7 +243,11 @@ export default class RedisMockCacheMgr extends CacheMgr { ? `${this.prefix}:${scope}:list` : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; log(`RedisMockCacheMgr::appendToList: append key ${key} to ${listKey}`); - const list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; + if (list.length && list[0] === 'NONE') { + list = []; + await this.del(listKey); + } list.push(key); return this.set(listKey, list); }