diff --git a/packages/backend-common/src/cache/CacheClient.test.ts b/packages/backend-common/src/cache/CacheClient.test.ts index 5d56d84c61..2e14fdbea1 100644 --- a/packages/backend-common/src/cache/CacheClient.test.ts +++ b/packages/backend-common/src/cache/CacheClient.test.ts @@ -19,6 +19,7 @@ import cacheManager from 'cache-manager'; describe('CacheClient', () => { const pluginId = 'test'; + const defaultTtl = 60; let client: cacheManager.Cache; const b64 = (k: string) => Buffer.from(k).toString('base64'); @@ -33,7 +34,7 @@ describe('CacheClient', () => { describe('CacheClient.get', () => { it('calls client with normalized key', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); const keyPartial = 'somekey'; await sut.get(keyPartial); @@ -42,7 +43,7 @@ describe('CacheClient', () => { }); it('calls client with normalized key (very long key)', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); const keyPartial = 'x'.repeat(251); await sut.get(keyPartial); @@ -55,7 +56,7 @@ describe('CacheClient', () => { it('performs deserialization on returned data', async () => { const expectedValue = { some: 'value' }; - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); client.get = jest.fn().mockResolvedValue(JSON.stringify(expectedValue)); const actualValue = await sut.get('someKey'); @@ -64,7 +65,7 @@ describe('CacheClient', () => { }); it('returns null on any underlying error', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); client.get = jest.fn().mockRejectedValue(undefined); const actualValue = await sut.get('someKey'); @@ -75,7 +76,7 @@ describe('CacheClient', () => { describe('CacheClient.set', () => { it('calls client with normalized key', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); const keyPartial = 'somekey'; await sut.set(keyPartial, {}); @@ -86,7 +87,7 @@ describe('CacheClient', () => { }); it('performs serialization on given data', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); const expectedData = { some: 'value' }; await sut.set('someKey', expectedData); @@ -97,7 +98,7 @@ describe('CacheClient', () => { }); it('passes ttl to client when given', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); const expectedTtl = 3600; await sut.set('someKey', {}, { ttl: expectedTtl }); @@ -107,8 +108,18 @@ describe('CacheClient', () => { expect(actualOptions.ttl).toEqual(expectedTtl); }); + it('passes defaultTtl to client when not', async () => { + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); + + await sut.set('someKey', {}); + + const spy = client.set as jest.Mock; + const actualOptions = spy.mock.calls[0][2]; + expect(actualOptions.ttl).toEqual(defaultTtl); + }); + it('does not throw errors on any client error', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); client.set = jest.fn().mockRejectedValue(undefined); expect(async () => { @@ -119,7 +130,7 @@ describe('CacheClient', () => { describe('CacheClient.delete', () => { it('calls client with normalized key', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); const keyPartial = 'somekey'; await sut.delete(keyPartial); @@ -130,7 +141,7 @@ describe('CacheClient', () => { }); it('does not throw errors on any client error', async () => { - const sut = new DefaultCacheClient({ client, pluginId }); + const sut = new DefaultCacheClient({ client, defaultTtl, pluginId }); client.del = jest.fn().mockRejectedValue(undefined); expect(async () => { diff --git a/packages/backend-common/src/cache/CacheClient.ts b/packages/backend-common/src/cache/CacheClient.ts index 68c762eb87..52703a28d4 100644 --- a/packages/backend-common/src/cache/CacheClient.ts +++ b/packages/backend-common/src/cache/CacheClient.ts @@ -21,6 +21,7 @@ import { createHash } from 'crypto'; type CacheClientArgs = { client: cacheManager.Cache; pluginId: string; + defaultTtl: number; }; type CacheSetOptions = { @@ -56,10 +57,12 @@ export interface CacheClient { */ export class DefaultCacheClient implements CacheClient { private readonly client: cacheManager.Cache; + private readonly defaultTtl: number; private readonly pluginId: string; - constructor({ client, pluginId }: CacheClientArgs) { + constructor({ client, defaultTtl, pluginId }: CacheClientArgs) { this.client = client; + this.defaultTtl = defaultTtl; this.pluginId = pluginId; } @@ -81,7 +84,9 @@ export class DefaultCacheClient implements CacheClient { const k = this.getNormalizedKey(key); try { const data = this.serializeData(value); - await this.client.set(k, data, opts.ttl ? { ttl: opts.ttl } : undefined); + await this.client.set(k, data, { + ttl: opts.ttl || this.defaultTtl, + }); } catch { return; } diff --git a/packages/backend-common/src/cache/CacheManager.ts b/packages/backend-common/src/cache/CacheManager.ts index 065a0b1db5..ecccbcf712 100644 --- a/packages/backend-common/src/cache/CacheManager.ts +++ b/packages/backend-common/src/cache/CacheManager.ts @@ -67,6 +67,7 @@ export class CacheManager { const concreteClient = this.getClientWithTtl(defaultTtl); return new DefaultCacheClient({ client: concreteClient, + defaultTtl, pluginId: pluginId, }); },