Exposes the useRedisSets config option for keyv redis

Signed-off-by: raffitamizian <r.tamizian@gmail.com>
This commit is contained in:
raffitamizian
2023-09-08 14:43:18 +01:00
parent 8d5e6825f1
commit 2a40cd46a8
4 changed files with 77 additions and 23 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Adds the optional flag for useRedisSets for the Redis cache to the config.
+3
View File
@@ -323,8 +323,11 @@ backend:
cache:
store: redis
connection: redis://user:pass@cache.example.com:6379
useRedisSets: true
```
The useRedisSets flag is explained [here](https://github.com/jaredwray/keyv/tree/main/packages/redis#useredissets).
Contributions supporting other cache stores are welcome!
## Containerization
+56 -22
View File
@@ -48,8 +48,10 @@ describe('CacheManager', () => {
describe('CacheManager.fromConfig', () => {
it('accesses the backend.cache key', () => {
const getOptionalString = jest.fn();
const getOptionalBoolean = jest.fn();
const config = defaultConfig();
config.getOptionalString = getOptionalString;
config.getOptionalBoolean = getOptionalBoolean;
CacheManager.fromConfig(config);
@@ -57,6 +59,9 @@ describe('CacheManager', () => {
expect(getOptionalString.mock.calls[1][0]).toEqual(
'backend.cache.connection',
);
expect(getOptionalBoolean.mock.calls[0][0]).toEqual(
'backend.cache.useRedisSets',
);
});
it('does not require the backend.cache key', () => {
@@ -195,32 +200,61 @@ describe('CacheManager', () => {
const mockMemcacheCalls = memcache.mock.calls.splice(-1);
expect(mockMemcacheCalls[0][0]).toEqual(expectedHost);
});
});
it('returns a Redis client when configured', () => {
const redisConnection = 'redis://127.0.0.1:6379';
const manager = CacheManager.fromConfig(
new ConfigReader({
backend: {
cache: {
store: 'redis',
connection: redisConnection,
it('returns a Redis client when configured', () => {
const redisConnection = 'redis://127.0.0.1:6379';
const manager = CacheManager.fromConfig(
new ConfigReader({
backend: {
cache: {
store: 'redis',
connection: redisConnection,
},
},
},
}),
);
const expectedTtl = 3600;
manager.forPlugin('test').getClient({ defaultTtl: expectedTtl });
}),
);
const expectedTtl = 3600;
manager.forPlugin('test').getClient({ defaultTtl: expectedTtl });
const cache = Keyv as unknown as jest.Mock;
const mockCacheCalls = cache.mock.calls.splice(-1);
expect(mockCacheCalls[0][0]).toMatchObject({
ttl: expectedTtl,
const cache = Keyv as unknown as jest.Mock;
const mockCacheCalls = cache.mock.calls.splice(-1);
expect(mockCacheCalls[0][0]).toMatchObject({
ttl: expectedTtl,
});
expect(mockCacheCalls[0][0].store).toBeInstanceOf(KeyvRedis);
const redis = KeyvRedis as unknown as jest.Mock;
const mockRedisCalls = redis.mock.calls.splice(-1);
expect(mockRedisCalls[0][0]).toEqual(redisConnection);
});
it('returns a Redis client when configured with useRedisSets flag', () => {
const redisConnection = 'redis://127.0.0.1:6379';
const useRedisSets = false;
const manager = CacheManager.fromConfig(
new ConfigReader({
backend: {
cache: {
store: 'redis',
connection: redisConnection,
useRedisSets: useRedisSets,
},
},
}),
);
const expectedTtl = 3600;
manager.forPlugin('test').getClient({ defaultTtl: expectedTtl });
const cache = Keyv as unknown as jest.Mock;
const mockCacheCalls = cache.mock.calls.splice(-1);
expect(mockCacheCalls[0][0]).toMatchObject({
ttl: expectedTtl,
useRedisSets: useRedisSets,
});
expect(mockCacheCalls[0][0].store).toBeInstanceOf(KeyvRedis);
const redis = KeyvRedis as unknown as jest.Mock;
const mockRedisCalls = redis.mock.calls.splice(-1);
expect(mockRedisCalls[0][0]).toEqual(redisConnection);
});
expect(mockCacheCalls[0][0].store).toBeInstanceOf(KeyvRedis);
const redis = KeyvRedis as unknown as jest.Mock;
const mockRedisCalls = redis.mock.calls.splice(-1);
expect(mockRedisCalls[0][0]).toEqual(redisConnection);
});
describe('connection errors', () => {
+13 -1
View File
@@ -55,6 +55,7 @@ export class CacheManager {
private readonly logger: LoggerService;
private readonly store: keyof CacheManager['storeFactories'];
private readonly connection: string;
private readonly useRedisSets: boolean;
private readonly errorHandler: CacheManagerOptions['onError'];
/**
@@ -72,15 +73,24 @@ export class CacheManager {
const store = config.getOptionalString('backend.cache.store') || 'memory';
const connectionString =
config.getOptionalString('backend.cache.connection') || '';
const useRedisSets =
config.getOptionalBoolean('backend.cache.useRedisSets') ?? true;
const logger = (options.logger || getRootLogger()).child({
type: 'cacheManager',
});
return new CacheManager(store, connectionString, logger, options.onError);
return new CacheManager(
store,
connectionString,
useRedisSets,
logger,
options.onError,
);
}
private constructor(
store: string,
connectionString: string,
useRedisSets: boolean,
logger: LoggerService,
errorHandler: CacheManagerOptions['onError'],
) {
@@ -90,6 +100,7 @@ export class CacheManager {
this.logger = logger;
this.store = store as keyof CacheManager['storeFactories'];
this.connection = connectionString;
this.useRedisSets = useRedisSets;
this.errorHandler = errorHandler;
}
@@ -143,6 +154,7 @@ export class CacheManager {
namespace: pluginId,
ttl: defaultTtl,
store: new KeyvRedis(this.connection),
useRedisSets: this.useRedisSets,
});
}