feat: add additional redis settings to redis locker

* feat: add additional redis settings to redis locker

* fix: unfinished doc
This commit is contained in:
Arthur Joppart 2022-11-02 10:48:30 +01:00 committed by GitHub
parent ef48660b48
commit 79fa83a07a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 6 deletions

View File

@ -16,6 +16,17 @@ const attemptDefaults: Required<AttemptSettings> = { retryCount: -1, retryDelay:
const PREFIX_RW = '__RW__'; const PREFIX_RW = '__RW__';
const PREFIX_LOCK = '__L__'; const PREFIX_LOCK = '__L__';
export interface RedisSettings {
/* Override default namespacePrefixes (used to prefix keys in Redis) */
namespacePrefix: string;
/* Username used for AUTH on the Redis server */
username?: string;
/* Password used for AUTH on the Redis server */
password?: string;
/* The number of the database to use */
db?: number;
}
/** /**
* A Redis Locker that can be used as both: * A Redis Locker that can be used as both:
* * a Read Write Locker that uses a (single) Redis server to store the locks and counts. * * a Read Write Locker that uses a (single) Redis server to store the locks and counts.
@ -57,10 +68,15 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab
* Creates a new RedisClient * Creates a new RedisClient
* @param redisClient - Redis connection string of a standalone Redis node * @param redisClient - Redis connection string of a standalone Redis node
* @param attemptSettings - Override default AttemptSettings * @param attemptSettings - Override default AttemptSettings
* @param namespacePrefix - Override default namespacePrefixes (used to prefix keys in Redis) * @param redisSettings - Addition settings used to create the Redis client or to interact with the Redis server
*/ */
public constructor(redisClient = '127.0.0.1:6379', attemptSettings: AttemptSettings = {}, namespacePrefix = '') { public constructor(
this.redis = this.createRedisClient(redisClient); redisClient = '127.0.0.1:6379',
attemptSettings: AttemptSettings = {},
redisSettings: RedisSettings = { namespacePrefix: '' },
) {
const { namespacePrefix, ...options } = redisSettings;
this.redis = this.createRedisClient(redisClient, options);
this.attemptSettings = { ...attemptDefaults, ...attemptSettings }; this.attemptSettings = { ...attemptDefaults, ...attemptSettings };
this.namespacePrefix = namespacePrefix; this.namespacePrefix = namespacePrefix;
@ -78,7 +94,7 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab
* @param redisClientString - A string that contains either a host address and a * @param redisClientString - A string that contains either a host address and a
* port number like '127.0.0.1:6379' or just a port number like '6379'. * port number like '127.0.0.1:6379' or just a port number like '6379'.
*/ */
private createRedisClient(redisClientString: string): Redis { private createRedisClient(redisClientString: string, options: Omit<RedisSettings, 'namespacePrefix'>): Redis {
if (redisClientString.length > 0) { if (redisClientString.length > 0) {
// Check if port number or ip with port number // Check if port number or ip with port number
// Definitely not perfect, but configuring this is only for experienced users // Definitely not perfect, but configuring this is only for experienced users
@ -90,7 +106,7 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab
} }
const port = Number(match[2]); const port = Number(match[2]);
const host = match[1]; const host = match[1];
return new Redis(port, host); return new Redis(port, host, options);
} }
throw new Error(`Empty redisClientString provided!\n throw new Error(`Empty redisClientString provided!\n
Please provide a port number like '6379' or a host address and a port number like '127.0.0.1:6379'`); Please provide a port number like '6379' or a host address and a port number like '127.0.0.1:6379'`);

View File

@ -103,7 +103,7 @@ jest.mock('ioredis', (): any => jest.fn().mockImplementation((): Redis => redis)
describe('A RedisLocker', (): void => { describe('A RedisLocker', (): void => {
it('will generate keys with the given namespacePrefix.', async(): Promise<void> => { it('will generate keys with the given namespacePrefix.', async(): Promise<void> => {
const identifier = { path: 'http://test.com/resource' }; const identifier = { path: 'http://test.com/resource' };
const lockerPrefixed = new RedisLocker('6379', {}, 'MY_PREFIX'); const lockerPrefixed = new RedisLocker('6379', {}, { namespacePrefix: 'MY_PREFIX' });
await lockerPrefixed.acquire(identifier); await lockerPrefixed.acquire(identifier);
const allLocksPrefixed = Object.keys(store.internal).every((key): boolean => key.startsWith('MY_PREFIX')); const allLocksPrefixed = Object.keys(store.internal).every((key): boolean => key.startsWith('MY_PREFIX'));
await lockerPrefixed.release(identifier); await lockerPrefixed.release(identifier);