update types, lock down client options

Signed-off-by: Mark Nachazel <markn@doordash.com>
This commit is contained in:
Mark Nachazel
2025-03-16 19:52:54 -04:00
parent fc1c605b9e
commit 893e8730b7
4 changed files with 84 additions and 5 deletions
+61
View File
@@ -559,6 +559,67 @@ export interface Config {
connection: string;
/** An optional default TTL (in milliseconds, if given as a number). */
defaultTtl?: number | HumanDuration | string;
redis?: {
/**
* An optional Redis client configuration. These options are passed to the `@keyv/redis` client.
*/
client?: {
/**
* Namespace for the current instance.
*/
namespace?: string;
/**
* Separator to use between namespace and key.
*/
keyPrefixSeparator?: string;
/**
* Number of keys to delete in a single batch.
*/
clearBatchSize?: number;
/**
* Enable Unlink instead of using Del for clearing keys. This is more performant but may not be supported by all Redis versions.
*/
useUnlink?: boolean;
/**
* Whether to allow clearing all keys when no namespace is set.
* If set to true and no namespace is set, iterate() will return all keys.
* Defaults to `false`.
*/
noNamespaceAffectsAll?: boolean;
};
/**
* An optional Redis cluster configuration.
*/
cluster?: {
/**
* Cluster configuration options to be passed to the `@keyv/redis` client (and node-redis under the hood)
* https://github.com/redis/node-redis/blob/master/docs/clustering.md
*
* @visibility secret
*/
rootNodes: Array<object>;
/**
* Cluster node default configuration options to be passed to the `@keyv/redis` client (and node-redis under the hood)
* https://github.com/redis/node-redis/blob/master/docs/clustering.md
*
* @visibility secret
*/
defaults?: Partial<object>;
/**
* When `true`, `.connect()` will only discover the cluster topology, without actually connecting to all the nodes.
* Useful for short-term or PubSub-only connections.
*/
minimizeConnections?: boolean;
/**
* When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes.
*/
useReplicas?: boolean;
/**
* The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors.
*/
maxCommandRedirections?: number;
};
};
}
| {
store: 'memcache';
@@ -226,7 +226,9 @@ describe('CacheManager store options', () => {
cache: {
store: 'redis',
connection: 'redis://localhost:6379',
cluster: {},
redis: {
cluster: {},
},
},
},
},
@@ -141,7 +141,16 @@ export class CacheManager {
const redisOptions: RedisCacheStoreOptions = {};
const redisConfig = config.getConfig(storeConfigPath);
redisOptions.client = redisConfig.getOptional('client');
redisOptions.client = {
namespace: redisConfig.getOptionalString('client.namespace'),
keyPrefixSeparator:
redisConfig.getOptionalString('client.keyPrefixSeparator') || ':',
clearBatchSize: redisConfig.getOptionalNumber('client.clearBatchSize'),
useUnlink: redisConfig.getOptionalBoolean('client.useUnlink'),
noNamespaceAffectsAll: redisConfig.getOptionalBoolean(
'client.noNamespaceAffectsAll',
),
};
if (redisConfig.has('cluster')) {
const clusterConfig = redisConfig.getConfig('cluster');
@@ -156,6 +165,13 @@ export class CacheManager {
redisOptions.cluster = {
rootNodes: clusterConfig.get('rootNodes'),
defaults: clusterConfig.getOptional('defaults'),
minimizeConnections: clusterConfig.getOptionalBoolean(
'minimizeConnections',
),
useReplicas: clusterConfig.getOptionalBoolean('useReplicas'),
maxCommandRedirections: clusterConfig.getOptionalNumber(
'maxCommandRedirections',
),
};
}
@@ -207,7 +223,7 @@ export class CacheManager {
private createRedisStoreFactory(): StoreFactory {
const KeyvRedis = require('@keyv/redis').default;
const { createCluster } = require('@keyv/redis');
const stores: Record<string, any> = {};
const stores: Record<string, typeof KeyvRedis> = {};
return (pluginId, defaultTtl) => {
if (!stores[pluginId]) {
+2 -2
View File
@@ -16,7 +16,7 @@
import { LoggerService } from '@backstage/backend-plugin-api';
import { HumanDuration, durationToMilliseconds } from '@backstage/types';
import { RedisClusterOptions, RedisClientOptions } from '@keyv/redis';
import { RedisClusterOptions, KeyvRedisOptions } from '@keyv/redis';
/**
* Options for Redis cache store.
@@ -24,7 +24,7 @@ import { RedisClusterOptions, RedisClientOptions } from '@keyv/redis';
* @public
*/
export type RedisCacheStoreOptions = {
client?: RedisClientOptions;
client?: KeyvRedisOptions;
cluster?: RedisClusterOptions;
};