diff --git a/packages/nocodb/src/cache/CacheMgr.ts b/packages/nocodb/src/cache/CacheMgr.ts index 0241f1c66b..544859a5af 100644 --- a/packages/nocodb/src/cache/CacheMgr.ts +++ b/packages/nocodb/src/cache/CacheMgr.ts @@ -1,6 +1,11 @@ export default abstract class CacheMgr { public abstract get(key: string, type: string): Promise; public abstract set(key: string, value: any): Promise; + public abstract setExpiring( + key: string, + value: any, + seconds: number, + ): Promise; public abstract del(key: string): Promise; public abstract getAll(pattern: string): Promise; public abstract delAll(scope: string, pattern: string): Promise; diff --git a/packages/nocodb/src/cache/NocoCache.ts b/packages/nocodb/src/cache/NocoCache.ts index f73473259a..15c2899640 100644 --- a/packages/nocodb/src/cache/NocoCache.ts +++ b/packages/nocodb/src/cache/NocoCache.ts @@ -29,6 +29,15 @@ export default class NocoCache { return this.client.set(`${this.prefix}:${key}`, value); } + public static async setExpiring(key, value, expireSeconds): Promise { + if (this.cacheDisabled) return Promise.resolve(true); + return this.client.setExpiring( + `${this.prefix}:${key}`, + value, + expireSeconds, + ); + } + public static async get(key, type): Promise { if (this.cacheDisabled) { if (type === CacheGetType.TYPE_ARRAY) return Promise.resolve([]); diff --git a/packages/nocodb/src/cache/RedisCacheMgr.ts b/packages/nocodb/src/cache/RedisCacheMgr.ts index f161d213e3..53b1de6a88 100644 --- a/packages/nocodb/src/cache/RedisCacheMgr.ts +++ b/packages/nocodb/src/cache/RedisCacheMgr.ts @@ -94,6 +94,30 @@ export default class RedisCacheMgr extends CacheMgr { } } + // @ts-ignore + async setExpiring(key: string, value: any, seconds: number): Promise { + if (typeof value !== 'undefined' && value) { + log( + `RedisCacheMgr::set: setting key ${key} with value ${value} for ${seconds} seconds`, + ); + if (typeof value === 'object') { + if (Array.isArray(value) && value.length) { + return this.client.sadd(key, value); + } + return this.client.set( + key, + JSON.stringify(value, this.getCircularReplacer()), + 'EX', + seconds, + ); + } + return this.client.set(key, value, 'EX', seconds); + } else { + log(`RedisCacheMgr::set: value is empty for ${key}. Skipping ...`); + return Promise.resolve(true); + } + } + // @ts-ignore async getAll(pattern: string): Promise { return this.client.hgetall(pattern); diff --git a/packages/nocodb/src/cache/RedisMockCacheMgr.ts b/packages/nocodb/src/cache/RedisMockCacheMgr.ts index ad9b2ca139..edb721f6b5 100644 --- a/packages/nocodb/src/cache/RedisMockCacheMgr.ts +++ b/packages/nocodb/src/cache/RedisMockCacheMgr.ts @@ -89,6 +89,34 @@ export default class RedisMockCacheMgr extends CacheMgr { } } + // @ts-ignore + async setExpiring(key: string, value: any, seconds: number): Promise { + if (typeof value !== 'undefined' && value) { + log( + `RedisMockCacheMgr::set: setting key ${key} with value ${value} for ${seconds} seconds`, + ); + + // TODO: better way to handle expiration in mock redis + setTimeout(() => { + this.del(key); + }, seconds * 1000); + + if (typeof value === 'object') { + if (Array.isArray(value) && value.length) { + return this.client.sadd(key, value); + } + return this.client.set( + key, + JSON.stringify(value, this.getCircularReplacer()), + ); + } + return this.client.set(key, value); + } else { + log(`RedisMockCacheMgr::set: value is empty for ${key}. Skipping ...`); + return Promise.resolve(true); + } + } + // @ts-ignore async getAll(pattern: string): Promise { return this.client.hgetall(pattern);