|
|
@ -6,12 +6,17 @@ const log = debug('nc:cache'); |
|
|
|
|
|
|
|
|
|
|
|
export default class RedisCacheMgr extends CacheMgr { |
|
|
|
export default class RedisCacheMgr extends CacheMgr { |
|
|
|
client: any; |
|
|
|
client: any; |
|
|
|
|
|
|
|
prefix: string; |
|
|
|
|
|
|
|
|
|
|
|
constructor(config: any) { |
|
|
|
constructor(config: any) { |
|
|
|
super(); |
|
|
|
super(); |
|
|
|
this.client = new Redis(config); |
|
|
|
this.client = new Redis(config); |
|
|
|
// flush the existing db with selected key (Default: 0)
|
|
|
|
// flush the existing db with selected key (Default: 0)
|
|
|
|
this.client.flushdb(); |
|
|
|
this.client.flushdb(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO(cache): fetch orgs once it's implemented
|
|
|
|
|
|
|
|
const orgs = 'noco'; |
|
|
|
|
|
|
|
this.prefix = `nc:${orgs}`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// avoid circular structure to JSON
|
|
|
|
// avoid circular structure to JSON
|
|
|
@ -91,10 +96,10 @@ export default class RedisCacheMgr extends CacheMgr { |
|
|
|
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
// @ts-ignore
|
|
|
|
async delAll(scope: string, pattern: string): Promise<any[]> { |
|
|
|
async delAll(scope: string, pattern: string): Promise<any[]> { |
|
|
|
// Example: model:*:<id>
|
|
|
|
// Example: nc:<orgs>:model:*:<id>
|
|
|
|
const keys = await this.client.keys(`${scope}:${pattern}`); |
|
|
|
const keys = await this.client.keys(`${this.prefix}:${scope}:${pattern}`); |
|
|
|
log( |
|
|
|
log( |
|
|
|
`RedisCacheMgr::delAll: deleting all keys with pattern ${scope}:${pattern}` |
|
|
|
`RedisCacheMgr::delAll: deleting all keys with pattern ${this.prefix}:${scope}:${pattern}` |
|
|
|
); |
|
|
|
); |
|
|
|
return Promise.all( |
|
|
|
return Promise.all( |
|
|
|
keys.map( |
|
|
|
keys.map( |
|
|
@ -107,12 +112,12 @@ export default class RedisCacheMgr extends CacheMgr { |
|
|
|
async getList(scope: string, subKeys: string[]): Promise<any[]> { |
|
|
|
async getList(scope: string, subKeys: string[]): Promise<any[]> { |
|
|
|
// remove null from arrays
|
|
|
|
// remove null from arrays
|
|
|
|
subKeys = subKeys.filter((k) => k); |
|
|
|
subKeys = subKeys.filter((k) => k); |
|
|
|
// e.g. key = <scope>:<project_id_1>:<base_id_1>:list
|
|
|
|
// e.g. key = nc:<orgs>:<scope>:<project_id_1>:<base_id_1>:list
|
|
|
|
const key = |
|
|
|
const key = |
|
|
|
subKeys.length === 0 |
|
|
|
subKeys.length === 0 |
|
|
|
? `${scope}:list` |
|
|
|
? `${this.prefix}:${scope}:list` |
|
|
|
: `${scope}:${subKeys.join(':')}:list`; |
|
|
|
: `${this.prefix}:${scope}:${subKeys.join(':')}:list`; |
|
|
|
// e.g. arr = ["<scope>:<model_id_1>", "<scope>:<model_id_2>"]
|
|
|
|
// e.g. arr = ["nc:<orgs>:<scope>:<model_id_1>", "nc:<orgs>:<scope>:<model_id_2>"]
|
|
|
|
const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
log(`RedisCacheMgr::getList: getting list with key ${key}`); |
|
|
|
log(`RedisCacheMgr::getList: getting list with key ${key}`); |
|
|
|
return Promise.all( |
|
|
|
return Promise.all( |
|
|
@ -128,11 +133,11 @@ export default class RedisCacheMgr extends CacheMgr { |
|
|
|
// remove null from arrays
|
|
|
|
// remove null from arrays
|
|
|
|
subListKeys = subListKeys.filter((k) => k); |
|
|
|
subListKeys = subListKeys.filter((k) => k); |
|
|
|
// construct key for List
|
|
|
|
// construct key for List
|
|
|
|
// e.g. <scope>:<project_id_1>:<base_id_1>:list
|
|
|
|
// e.g. nc:<orgs>:<scope>:<project_id_1>:<base_id_1>:list
|
|
|
|
const listKey = |
|
|
|
const listKey = |
|
|
|
subListKeys.length === 0 |
|
|
|
subListKeys.length === 0 |
|
|
|
? `${scope}:list` |
|
|
|
? `${this.prefix}:${scope}:list` |
|
|
|
: `${scope}:${subListKeys.join(':')}:list`; |
|
|
|
: `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; |
|
|
|
if (!list.length) { |
|
|
|
if (!list.length) { |
|
|
|
log(`RedisCacheMgr::setList: List is empty for ${listKey}. Skipping ...`); |
|
|
|
log(`RedisCacheMgr::setList: List is empty for ${listKey}. Skipping ...`); |
|
|
|
return Promise.resolve(true); |
|
|
|
return Promise.resolve(true); |
|
|
@ -142,11 +147,11 @@ export default class RedisCacheMgr extends CacheMgr { |
|
|
|
(await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
(await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
for (const o of list) { |
|
|
|
for (const o of list) { |
|
|
|
// construct key for Get
|
|
|
|
// construct key for Get
|
|
|
|
// e.g. <scope>:<model_id_1>
|
|
|
|
// e.g. nc:<orgs>:<scope>:<model_id_1>
|
|
|
|
let getKey = `${scope}:${o.id}`; |
|
|
|
let getKey = `${this.prefix}:${scope}:${o.id}`; |
|
|
|
// special case - MODEL_ROLE_VISIBILITY
|
|
|
|
// special case - MODEL_ROLE_VISIBILITY
|
|
|
|
if (scope === CacheScope.MODEL_ROLE_VISIBILITY) { |
|
|
|
if (scope === CacheScope.MODEL_ROLE_VISIBILITY) { |
|
|
|
getKey = `${scope}:${o.id}:${o.role}`; |
|
|
|
getKey = `${this.prefix}:${scope}:${o.id}:${o.role}`; |
|
|
|
} |
|
|
|
} |
|
|
|
// set Get Key
|
|
|
|
// set Get Key
|
|
|
|
log(`RedisCacheMgr::setList: setting key ${getKey}`); |
|
|
|
log(`RedisCacheMgr::setList: setting key ${getKey}`); |
|
|
@ -164,10 +169,11 @@ export default class RedisCacheMgr extends CacheMgr { |
|
|
|
key: string, |
|
|
|
key: string, |
|
|
|
direction: string |
|
|
|
direction: string |
|
|
|
): Promise<boolean> { |
|
|
|
): Promise<boolean> { |
|
|
|
|
|
|
|
key = `${this.prefix}:${key}`; |
|
|
|
log(`RedisCacheMgr::deepDel: choose direction ${direction}`); |
|
|
|
log(`RedisCacheMgr::deepDel: choose direction ${direction}`); |
|
|
|
if (direction === CacheDelDirection.CHILD_TO_PARENT) { |
|
|
|
if (direction === CacheDelDirection.CHILD_TO_PARENT) { |
|
|
|
// given a child key, delete all keys in corresponding parent lists
|
|
|
|
// given a child key, delete all keys in corresponding parent lists
|
|
|
|
const scopeList = await this.client.keys(`${scope}*list`); |
|
|
|
const scopeList = await this.client.keys(`${this.prefix}:${scope}*list`); |
|
|
|
for (const listKey of scopeList) { |
|
|
|
for (const listKey of scopeList) { |
|
|
|
// get target list
|
|
|
|
// get target list
|
|
|
|
let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; |
|
|
@ -208,11 +214,11 @@ export default class RedisCacheMgr extends CacheMgr { |
|
|
|
): Promise<boolean> { |
|
|
|
): Promise<boolean> { |
|
|
|
// remove null from arrays
|
|
|
|
// remove null from arrays
|
|
|
|
subListKeys = subListKeys.filter((k) => k); |
|
|
|
subListKeys = subListKeys.filter((k) => k); |
|
|
|
// e.g. key = <scope>:<project_id_1>:<base_id_1>:list
|
|
|
|
// e.g. key = nc:<orgs>:<scope>:<project_id_1>:<base_id_1>:list
|
|
|
|
const listKey = |
|
|
|
const listKey = |
|
|
|
subListKeys.length === 0 |
|
|
|
subListKeys.length === 0 |
|
|
|
? `${scope}:list` |
|
|
|
? `${this.prefix}:${scope}:list` |
|
|
|
: `${scope}:${subListKeys.join(':')}:list`; |
|
|
|
: `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; |
|
|
|
log(`RedisCacheMgr::appendToList: append key ${key} to ${listKey}`); |
|
|
|
log(`RedisCacheMgr::appendToList: append key ${key} to ${listKey}`); |
|
|
|
const list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
const list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; |
|
|
|
list.push(key); |
|
|
|
list.push(key); |
|
|
|