UNPKG

layered-loader

Version:

Data loader with support for caching and fallback data sources

105 lines 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RedisCache = void 0; const Loader_1 = require("../Loader"); const AbstractRedisCache_1 = require("./AbstractRedisCache"); const RedisExpirationTimeDataSource_1 = require("./RedisExpirationTimeDataSource"); class RedisCache extends AbstractRedisCache_1.AbstractRedisCache { expirationTimeLoadingOperation; ttlLeftBeforeRefreshInMsecs; name = 'Redis cache'; constructor(redis, config = AbstractRedisCache_1.DEFAULT_REDIS_CACHE_CONFIGURATION) { super(redis, config); this.ttlLeftBeforeRefreshInMsecs = config.ttlLeftBeforeRefreshInMsecs; if (!this.ttlLeftBeforeRefreshInMsecs && config.ttlCacheTtl) { throw new Error('ttlCacheTtl cannot be specified if ttlLeftBeforeRefreshInMsecs is not.'); } this.expirationTimeLoadingOperation = new Loader_1.Loader({ inMemoryCache: config.ttlCacheTtl ? { cacheId: 'ttl-cache', ttlInMsecs: config.ttlCacheTtl, maxItems: config.ttlCacheSize ?? 500, } : undefined, dataSources: [new RedisExpirationTimeDataSource_1.RedisExpirationTimeDataSource(this)], }); } delete(key) { return this.redis.del(this.resolveKey(key)); } deleteMany(keys) { const processedKeys = keys.map((key) => { return this.resolveKey(key); }); return this.redis.del(processedKeys); } get(key) { return this.redis.get(this.resolveKey(key)).then((redisResult) => { return this.postprocessResult(redisResult); }); } getMany(keys) { const transformedKeys = keys.map((entry) => this.resolveKey(entry)); const resolvedValues = []; const unresolvedKeys = []; return this.redis.mget(transformedKeys).then((redisResult) => { for (let i = 0; i < keys.length; i++) { const currentResult = redisResult[i]; if (currentResult !== null) { resolvedValues.push(this.postprocessResult(currentResult)); } else { unresolvedKeys.push(keys[i]); } } return { resolvedValues, unresolvedKeys, }; }); } getExpirationTime(key) { const now = Date.now(); return this.redis.pttl(this.resolveKey(key)).then((remainingTtl) => { return remainingTtl && remainingTtl > 0 ? now + remainingTtl : undefined; }); } set(key, value) { return this.internalSet(this.resolveKey(key), value).then(() => { if (this.ttlLeftBeforeRefreshInMsecs) { void this.expirationTimeLoadingOperation.invalidateCacheFor(key); } }); } setMany(entries) { if (this.config.ttlInMsecs) { const setCommands = []; for (let i = 0; i < entries.length; i++) { const entry = entries[i]; setCommands.push([ 'set', this.resolveKey(entry.key), entry.value && this.config.json ? JSON.stringify(entry.value) : entry.value, 'PX', this.config.ttlInMsecs, ]); } return this.redis.multi(setCommands).exec(); } // No TTL set const commandParam = []; for (let i = 0; i < entries.length; i++) { const entry = entries[i]; commandParam.push(this.resolveKey(entry.key)); commandParam.push(entry.value && this.config.json ? JSON.stringify(entry.value) : entry.value); } return this.redis.mset(commandParam); } async close() { // prevent refreshes after everything is shutting down to prevent "Error: Connection is closed." errors this.ttlLeftBeforeRefreshInMsecs = 0; } } exports.RedisCache = RedisCache; //# sourceMappingURL=RedisCache.js.map