UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

92 lines 3.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.cache = cache; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const luxon_1 = require("luxon"); const global_1 = require("../../../config/global"); const logger_1 = require("../../../logger"); const decorator_1 = require("../../decorator"); const mutex_1 = require("../../mutex"); const ttl_1 = require("./ttl"); const packageCache = tslib_1.__importStar(require(".")); /** * caches the result of a decorated method. */ function cache({ namespace, key, cacheable = () => true, ttlMinutes = 30, }) { return (0, decorator_1.decorate)(async ({ args, instance, callback, methodName }) => { const cachePrivatePackages = global_1.GlobalConfig.get('cachePrivatePackages', false); const isCacheable = cachePrivatePackages || cacheable.apply(instance, args); if (!isCacheable) { return callback(); } let finalNamespace; if (is_1.default.string(namespace)) { finalNamespace = namespace; } else if (is_1.default.function(namespace)) { finalNamespace = namespace.apply(instance, args); } let finalKey; if (is_1.default.string(key)) { finalKey = key; } else if (is_1.default.function(key)) { finalKey = key.apply(instance, args); } // istanbul ignore if if (!finalNamespace || !finalKey) { return callback(); } finalKey = `cache-decorator:${finalKey}`; // prevent concurrent processing and cache writes const releaseLock = await (0, mutex_1.acquireLock)(finalKey, finalNamespace); try { const oldRecord = await packageCache.get(finalNamespace, finalKey); const ttlValues = (0, ttl_1.resolveTtlValues)(finalNamespace, ttlMinutes); const softTtl = ttlValues.softTtlMinutes; const hardTtl = methodName === 'getReleases' || methodName === 'getDigest' ? ttlValues.hardTtlMinutes : // Skip two-tier TTL for any intermediate data fetching softTtl; let oldData; if (oldRecord) { const now = luxon_1.DateTime.local(); const cachedAt = luxon_1.DateTime.fromISO(oldRecord.cachedAt); const softDeadline = cachedAt.plus({ minutes: softTtl }); if (now < softDeadline) { return oldRecord.value; } const hardDeadline = cachedAt.plus({ minutes: hardTtl }); if (now < hardDeadline) { oldData = oldRecord.value; } } let newData; if (oldData) { try { newData = (await callback()); } catch (err) { logger_1.logger.debug({ err }, 'Package cache decorator: callback error, returning old data'); return oldData; } } else { newData = (await callback()); } if (!is_1.default.undefined(newData)) { const newRecord = { cachedAt: luxon_1.DateTime.local().toISO(), value: newData, }; await packageCache.set(finalNamespace, finalKey, newRecord, hardTtl); } return newData; } finally { releaseLock(); } }); } //# sourceMappingURL=decorator.js.map