UNPKG

blue-fish-redis

Version:
146 lines (145 loc) 5.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RedisCache = void 0; const blue_fish_helper_1 = require("blue-fish-helper"); const coa_error_1 = require("coa-error"); const ms_ttl = 30 * 24 * 3600 * 1000; class RedisCache { constructor(bin) { this.io = bin.io; this.config = bin.config; } // 设置 async set(nsp, id, value, ms = ms_ttl) { ms > 0 || coa_error_1.CoaError.throw('RedisCache.InvalidParam', 'cache hash ms 必须大于0'); const expire = blue_fish_helper_1._.now() + ms; const data = this.encode(value, expire); return await this.io.hset(this.key(nsp), id, data); } // 批量设置 async mSet(nsp, values, ms = ms_ttl) { ms > 0 || coa_error_1.CoaError.throw('RedisCache.InvalidParam', 'cache hash ms 必须大于0'); blue_fish_helper_1._.keys(values).length > 0 || coa_error_1.CoaError.throw('RedisCache.InvalidParam', 'cache hash values值的数量 必须大于0'); const expire = Date.now() + ms; const data = {}; blue_fish_helper_1._.forEach(values, (v, k) => (data[k] = this.encode(v, expire))); return await this.io.hmset(this.key(nsp), data); } // 获取 async get(nsp, id) { var _a; const ret = (_a = (await this.io.hget(this.key(nsp), id))) !== null && _a !== void 0 ? _a : ''; return this.decode(ret, blue_fish_helper_1._.now()); } // 批量获取 async mGet(nsp, ids) { const ret = await this.io.hmget(this.key(nsp), ...ids); const result = {}; const time = blue_fish_helper_1._.now(); blue_fish_helper_1._.forEach(ids, (id, i) => (result[id] = this.decode(ret[i], time))); return result; } // 获取 async warp(nsp, id, worker, ms = ms_ttl, force = false) { let result = force ? undefined : await this.get(nsp, id); if (result === undefined) { result = await worker(); ms > 0 && (await this.set(nsp, id, result, ms)); } return result; } // 获取 async mWarp(nsp, ids, worker, ms = ms_ttl, force = false) { const result = force ? {} : await this.mGet(nsp, ids); const newIds = []; blue_fish_helper_1._.forEach(ids, id => { if (result[id] === undefined) newIds.push(id); }); if (newIds.length) { const newResult = (await worker(newIds)); blue_fish_helper_1._.forEach(newIds, id => { if (!newResult[id]) newResult[id] = null; }); ms > 0 && (await this.mSet(nsp, newResult, ms)); blue_fish_helper_1._.extend(result, newResult); } return result; } // 删除 async delete(nsp, ids = []) { if (ids.length) return await this.io.hdel(this.key(nsp), ...ids); else return await this.io.del(this.key(nsp)); } // 删除 async mDelete(deleteIds) { if (deleteIds.length === 0) return 0; else if (deleteIds.length === 1) return await this.delete(...deleteIds[0]); const pipeline = this.io.pipeline(); deleteIds.forEach(([nsp, ids]) => { ids.length ? pipeline.hdel(this.key(nsp), ...ids) : pipeline.del(this.key(nsp)); }); return await pipeline.exec(); } // 清除无效的缓存 async clearUseless(match = '*') { const now = blue_fish_helper_1._.now(); const keys1 = await this.io.keys(this.key(match)); const result = {}; // 循环处理每一个key for (const key1 of keys1) { // 按1000分组 const keys2 = await this.io.hkeys(key1); const keys2Chunks = blue_fish_helper_1._.chunk(keys2, 1000); result[key1] = [0, keys2.length]; for (const keys2 of keys2Chunks) { // 批量获取 const values = await this.io.hmget(key1, keys2); const deleteIds = []; // 判断是否过期 blue_fish_helper_1._.forEach(values, (value, index) => { const expire = blue_fish_helper_1._.toInteger((value || '').substring(1, 14)); if (expire < now) deleteIds.push(keys2[index]); }); // 删除过期的 if (deleteIds.length) await this.io.hdel(key1, ...deleteIds); result[key1][0] += deleteIds.length; } } return result; } // 清除指定命名空间的缓存 async clear(nsp = '') { const keys = await this.io.keys(this.key(nsp + '*')); return keys.length ? await this.io.del(...keys) : 0; } // 设置nsp key(nsp) { return this.config.prefix + ':' + nsp; } encode(value, expire) { if (value === undefined) value = null; return JSON.stringify([expire, value]); } decode(value, time) { if (!value) return undefined; try { const data = JSON.parse(value); const expire = data[0] || 0; return expire < time ? undefined : data[1]; } catch (e) { return undefined; } } } exports.RedisCache = RedisCache;