diff --git a/lib/globals.d.ts b/lib/globals.d.ts index 79df2b6aedf0cf870e099cd23b218e149dc5227a..2eeb507f25fcec3e8d682fd78664646fd457adea 100644 --- a/lib/globals.d.ts +++ b/lib/globals.d.ts @@ -2,20 +2,6 @@ * This file should be removed in future. */ -declare namespace Renovate { - interface Cache { - get<T = any>(namespace: string, key: string): Promise<T>; - rm(namespace: string, key: string): Promise<void>; - - set<T = any>( - namespace: string, - key: string, - value: T, - ttlMinutes?: number - ): Promise<void>; - } -} - declare interface Error { configFile?: string; @@ -30,14 +16,10 @@ declare namespace NodeJS { appMode?: boolean; gitAuthor?: { name: string; email: string }; - renovateCache: Renovate.Cache; - trustLevel?: string; } } -declare let renovateCache: Renovate.Cache; - // can't use `resolveJsonModule` because it will copy json files and change dist path declare module '*.json' { const value: { version: string } & Record<string, any>; diff --git a/lib/util/cache/global/common.ts b/lib/util/cache/global/common.ts new file mode 100644 index 0000000000000000000000000000000000000000..0742921000bc7ca2cf02df4b9f58253e825e661f --- /dev/null +++ b/lib/util/cache/global/common.ts @@ -0,0 +1,10 @@ +export interface GlobalCache { + get<T = any>(namespace: string, key: string): Promise<T>; + + set<T = any>( + namespace: string, + key: string, + value: T, + ttlMinutes?: number + ): Promise<void>; +} diff --git a/lib/util/cache/global/file.spec.ts b/lib/util/cache/global/file.spec.ts index 26be177a9c864985192f6f0061a7394f797044f3..d4d26fcac869ce94e781244bc83e6cb031fc1b3b 100644 --- a/lib/util/cache/global/file.spec.ts +++ b/lib/util/cache/global/file.spec.ts @@ -1,24 +1,25 @@ import os from 'os'; -import { init } from './file'; +import { get, init, set } from './file'; describe('lib/util/cache/global/file', () => { - beforeAll(() => { - init(os.tmpdir()); + it('returns if uninitiated', async () => { + await set('test', 'key', 1234); + expect(await get('test', 'key')).toBeUndefined(); }); - it('gets null', async () => { - expect( - await global.renovateCache.get('test', 'missing-key') - ).toBeUndefined(); + init(os.tmpdir()); + expect(await get('test', 'missing-key')).toBeUndefined(); }); it('sets and gets', async () => { - await global.renovateCache.set('test', 'key', 1234); - expect(await global.renovateCache.get('test', 'key')).toBe(1234); + init(os.tmpdir()); + await set('test', 'key', 1234); + expect(await get('test', 'key')).toBe(1234); }); it('expires', async () => { - await global.renovateCache.set('test', 'key', 1234, -5); - expect(await global.renovateCache.get('test', 'key')).toBeUndefined(); + init(os.tmpdir()); + await set('test', 'key', 1234, -5); + expect(await get('test', 'key')).toBeUndefined(); }); }); diff --git a/lib/util/cache/global/file.ts b/lib/util/cache/global/file.ts index 0fcbda3010bd78005798261733764f30b8c301f9..e517e612b1320b09c860cdd885f6b530f8561133 100644 --- a/lib/util/cache/global/file.ts +++ b/lib/util/cache/global/file.ts @@ -7,16 +7,22 @@ function getKey(namespace: string, key: string): string { return `${namespace}-${key}`; } -let renovateCache: string; +let cacheFileName: string; async function rm(namespace: string, key: string): Promise<void> { logger.trace({ namespace, key }, 'Removing cache entry'); - await cacache.rm.entry(renovateCache, getKey(namespace, key)); + await cacache.rm.entry(cacheFileName, getKey(namespace, key)); } -async function get<T = never>(namespace: string, key: string): Promise<T> { +export async function get<T = never>( + namespace: string, + key: string +): Promise<T> { + if (!cacheFileName) { + return undefined; + } try { - const res = await cacache.get(renovateCache, getKey(namespace, key)); + const res = await cacache.get(cacheFileName, getKey(namespace, key)); const cachedValue = JSON.parse(res.data.toString()); if (cachedValue) { if (DateTime.local() < DateTime.fromISO(cachedValue.expiry)) { @@ -31,15 +37,18 @@ async function get<T = never>(namespace: string, key: string): Promise<T> { return undefined; } -async function set( +export async function set( namespace: string, key: string, value: unknown, ttlMinutes = 5 ): Promise<void> { + if (!cacheFileName) { + return; + } logger.trace({ namespace, key, ttlMinutes }, 'Saving cached value'); await cacache.put( - renovateCache, + cacheFileName, getKey(namespace, key), JSON.stringify({ value, @@ -49,7 +58,6 @@ async function set( } export function init(cacheDir: string): void { - renovateCache = path.join(cacheDir, '/renovate/renovate-cache-v1'); - logger.debug('Initializing Renovate internal cache into ' + renovateCache); - global.renovateCache = global.renovateCache || { get, set, rm }; + cacheFileName = path.join(cacheDir, '/renovate/renovate-cache-v1'); + logger.debug('Initializing Renovate internal cache into ' + cacheFileName); } diff --git a/lib/util/cache/global/index.spec.ts b/lib/util/cache/global/index.spec.ts index d88d80496a5e35b603ecbd3f5bebb9efc61b751e..c91c9d1abeca279f003426da5609b182a07ceec3 100644 --- a/lib/util/cache/global/index.spec.ts +++ b/lib/util/cache/global/index.spec.ts @@ -10,7 +10,6 @@ describe(getName(__filename), () => { expect(await set('test', 'some-key', 'some-value', 5)).toBeUndefined(); }); it('sets and gets file', async () => { - global.renovateCache = { get: jest.fn(), set: jest.fn(), rm: jest.fn() }; init({ cacheDir: 'some-dir' }); expect( await set('some-namespace', 'some-key', 'some-value', 1) @@ -18,7 +17,6 @@ describe(getName(__filename), () => { expect(await get('some-namespace', 'unknown-key')).toBeUndefined(); }); it('sets and gets redis', async () => { - global.renovateCache = { get: jest.fn(), set: jest.fn(), rm: jest.fn() }; init({ redisUrl: 'some-url' }); expect( await set('some-namespace', 'some-key', 'some-value', 1) diff --git a/lib/util/cache/global/index.ts b/lib/util/cache/global/index.ts index 055f01cae922ab31a72046d3597789e4c3314d71..0fb6a2819aa11f4030eada0c508b418e0882546a 100644 --- a/lib/util/cache/global/index.ts +++ b/lib/util/cache/global/index.ts @@ -1,19 +1,22 @@ import { RenovateConfig } from '../../../config/common'; import * as runCache from '../run'; +import { GlobalCache } from './common'; import * as fileCache from './file'; import * as redisCache from './redis'; +let cacheProxy: GlobalCache; + function getGlobalKey(namespace: string, key: string): string { return `global%%${namespace}%%${key}`; } export function get<T = any>(namespace: string, key: string): Promise<T> { - if (!global.renovateCache) { + if (!cacheProxy) { return undefined; } const globalKey = getGlobalKey(namespace, key); if (!runCache.get(globalKey)) { - runCache.set(globalKey, global.renovateCache.get(namespace, key)); + runCache.set(globalKey, cacheProxy.get(namespace, key)); } return runCache.get(globalKey); } @@ -24,19 +27,27 @@ export function set( value: any, minutes: number ): Promise<void> { - if (!global.renovateCache) { + if (!cacheProxy) { return undefined; } const globalKey = getGlobalKey(namespace, key); runCache.set(globalKey, value); - return global.renovateCache.set(namespace, key, value, minutes); + return cacheProxy.set(namespace, key, value, minutes); } export function init(config: RenovateConfig): void { if (config.redisUrl) { redisCache.init(config.redisUrl); + cacheProxy = { + get: redisCache.get, + set: redisCache.set, + }; } else { fileCache.init(config.cacheDir); + cacheProxy = { + get: fileCache.get, + set: fileCache.set, + }; } } diff --git a/lib/util/cache/global/redis.ts b/lib/util/cache/global/redis.ts index bd3406837fe808cfb5535f9f9818598afcb7e470..b86f7e05b82246a7a59174b7a4f048d1c8e75785 100644 --- a/lib/util/cache/global/redis.ts +++ b/lib/util/cache/global/redis.ts @@ -22,7 +22,13 @@ async function rm(namespace: string, key: string): Promise<void> { await client?.del(getKey(namespace, key)); } -async function get<T = never>(namespace: string, key: string): Promise<T> { +export async function get<T = never>( + namespace: string, + key: string +): Promise<T> { + if (!client) { + return undefined; + } logger.trace(`cache.get(${namespace}, ${key})`); try { const res = await client?.get(getKey(namespace, key)); @@ -41,7 +47,7 @@ async function get<T = never>(namespace: string, key: string): Promise<T> { return undefined; } -async function set( +export async function set( namespace: string, key: string, value: unknown, @@ -73,5 +79,4 @@ export function init(url: string): void { return Math.min(options.attempt * 100, 3000); }, }); - global.renovateCache = { get, set, rm }; }