Skip to content

Commit

Permalink
Added config in connect() + url fixed adding redis://
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Hapes committed Jul 26, 2023
1 parent 2c222ef commit b7a49da
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 15 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [2.3.0] - 2023-07-26
### Added
- Optional parameter `config` in `connect()` method for receiving `url`.

### Changed
- Now `url` are fixed adding `redis://` in the beginning or the url when not received.

## [2.2.0] - 2023-06-30
### Added
- Using env variable `REDIS_CLUSTER_MODE` for cluster connection.
Expand Down
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ npm install @janiscommerce/redis

If the env vars `REDIS_WRITE_URL` is set, will create a Redis connection

#### Config object parameter

_Since 2.3.0_

The `connect()` allows to receive an object with the `url`.

#### Settings

> :warning: **Deprecated** :warning:
Expand All @@ -46,15 +52,28 @@ See an example below

The env var `REDIS_CLUSTER_MODE` must be set with a truthy value.

Then, the env vars `REDIS_WRITE_URL` and `REDIS_READ_URL` will be used for creating a Redis cluster connection.
#### Env Vars

If the env vars `REDIS_WRITE_URL` and `REDIS_READ_URL` will be used for creating a Redis cluster connection.

#### Config object parameter

_Since 2.3.0_

The `connect()` allows to receive an object with the `url` as _String_ or _String Array_.

## API

### `connect()`
### `connect(config = {})`

**async** | Connects the Redis server using settings.

Returns:
#### Parameters
- `config` the optional configuration.
- `config.url` optional url as _String_ for connecting the client of cluster. _Since 2.3.0_
- `config.url` optional url as _String Array_ for connecting. Exclusive for in cluster mode. _Since 2.3.0_

#### Return
* `client`: The Redis client when `host` is present in settings.
* `undefined`: When `host` is not present in settings.

Expand Down
26 changes: 20 additions & 6 deletions lib/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,42 @@ module.exports = class Redis {
return Settings.get(SETTINGS_KEY); // internal cache already implemented by Settings package
}

static async connect() {
static async connect({ url } = {}) {

if(conn)
return conn;

if(process.env.REDIS_CLUSTER_MODE) {

if(url && !Array.isArray(url))
url = [url];

const urls = [
...[process.env.REDIS_WRITE_URL || false],
...[process.env.REDIS_READ_URL || false]
...[process.env.REDIS_READ_URL || false],
...Array.isArray(url) ? url : []
].filter(Boolean);

if(!urls.length)
return;

conn = RedisLib.createCluster({
rootNodes: urls.map(url => ({ url })),
rootNodes: urls.map(clusterUrl => ({
url: this.formatUrl(clusterUrl)
})),
useReplicas: true
});

} else {

const url = process.env.REDIS_WRITE_URL || this.config?.host;
url = url || process.env.REDIS_WRITE_URL || this.config?.host;

if(!url)
if(typeof url !== 'string')
return;

conn = RedisLib.createClient({ url });
conn = RedisLib.createClient({
url: this.formatUrl(url)
});
}

conn.on('error', err => logger.error(`Redis Client Error - ${err.message}`));
Expand All @@ -69,6 +77,12 @@ module.exports = class Redis {
Redis.cleanConn();
}

static formatUrl(url) {
return url.indexOf('redis://') === -1
? `redis://${url}`
: url;
}

static cleanConn() {
conn = null;
}
Expand Down
96 changes: 90 additions & 6 deletions tests/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,35 @@ describe('Redis', () => {
sinon.assert.notCalled(RedisLib.createCluster);
});

it('Should create Redis client when configured using url parameter in connect()', async () => {

const connectStub = sinon.stub().resolves();
const quitStub = sinon.stub().resolves();
const on = sinon.stub();

const conn = { connect: connectStub, quit: quitStub, on };

stubSettings();

sinon.stub(RedisLib, 'createClient')
.returns(conn);

const createdConn = await Redis.connect({ url: 'redis://write.redis.my-service.com' });

await Events.emit('janiscommerce.ended');

assert.deepStrictEqual(createdConn, conn);

sinon.assert.calledOnceWithExactly(RedisLib.createClient, {
url: 'redis://write.redis.my-service.com'
});

sinon.assert.calledOnceWithExactly(connectStub);

sinon.assert.notCalled(Settings.get);
sinon.assert.calledOnceWithExactly(on, 'error', sinon.match.func);
});

it('Should create Redis client when configured using env var REDIS_WRITE_URL', async () => {

process.env.REDIS_WRITE_URL = 'write.redis.my-service.com';
Expand All @@ -62,7 +91,7 @@ describe('Redis', () => {
assert.deepStrictEqual(createdConn, conn);

sinon.assert.calledOnceWithExactly(RedisLib.createClient, {
url: 'write.redis.my-service.com'
url: 'redis://write.redis.my-service.com'
});

sinon.assert.calledOnceWithExactly(connectStub);
Expand Down Expand Up @@ -91,7 +120,7 @@ describe('Redis', () => {
assert.deepStrictEqual(createdConn, conn);

sinon.assert.calledOnceWithExactly(RedisLib.createClient, {
url: 'redis.my-service.com'
url: 'redis://redis.my-service.com'
});

sinon.assert.calledOnceWithExactly(connectStub);
Expand Down Expand Up @@ -124,7 +153,7 @@ describe('Redis', () => {
assert.deepStrictEqual(otherConnConn, conn);

sinon.assert.calledOnceWithExactly(RedisLib.createClient, {
url: 'write.redis.my-service.com'
url: 'redis://write.redis.my-service.com'
});

sinon.assert.calledOnceWithExactly(connectStub);
Expand Down Expand Up @@ -164,6 +193,61 @@ describe('Redis', () => {
sinon.assert.notCalled(RedisLib.createClient);
});

it('Should create Redis cluster using url parameter as string in connect()', async () => {

const connectStub = sinon.stub().resolves();
const quitStub = sinon.stub().resolves();
const on = sinon.stub();

const cluster = { connect: connectStub, quit: quitStub, on };

sinon.stub(RedisLib, 'createCluster')
.returns(cluster);

const createdConn = await Redis.connect({ url: 'write.redis.my-service.com' });

await Events.emit('janiscommerce.ended');

assert.deepStrictEqual(createdConn, cluster);

sinon.assert.calledOnceWithExactly(RedisLib.createCluster, {
rootNodes: [{ url: 'redis://write.redis.my-service.com' }],
useReplicas: true
});

sinon.assert.calledOnceWithExactly(connectStub);
sinon.assert.calledOnceWithExactly(on, 'error', sinon.match.func);
});

it('Should create Redis cluster using parameter with multiple urls in connect()', async () => {

const connectStub = sinon.stub().resolves();
const quitStub = sinon.stub().resolves();
const on = sinon.stub();

const cluster = { connect: connectStub, quit: quitStub, on };

sinon.stub(RedisLib, 'createCluster')
.returns(cluster);

const createdConn = await Redis.connect({ url: ['write.redis.my-service.com', 'read.redis.my-service.com'] });

await Events.emit('janiscommerce.ended');

assert.deepStrictEqual(createdConn, cluster);

sinon.assert.calledOnceWithExactly(RedisLib.createCluster, {
rootNodes: [
{ url: 'redis://write.redis.my-service.com' },
{ url: 'redis://read.redis.my-service.com' }
],
useReplicas: true
});

sinon.assert.calledOnceWithExactly(connectStub);
sinon.assert.calledOnceWithExactly(on, 'error', sinon.match.func);
});

it('Should create Redis cluster using env vars REDIS_WRITE_URL', async () => {

process.env.REDIS_WRITE_URL = 'write.redis.my-service.com';
Expand All @@ -184,7 +268,7 @@ describe('Redis', () => {
assert.deepStrictEqual(createdConn, cluster);

sinon.assert.calledOnceWithExactly(RedisLib.createCluster, {
rootNodes: [{ url: 'write.redis.my-service.com' }],
rootNodes: [{ url: 'redis://write.redis.my-service.com' }],
useReplicas: true
});

Expand Down Expand Up @@ -214,8 +298,8 @@ describe('Redis', () => {

sinon.assert.calledOnceWithExactly(RedisLib.createCluster, {
rootNodes: [
{ url: 'write.redis.my-service.com' },
{ url: 'read.redis.my-service.com' }
{ url: 'redis://write.redis.my-service.com' },
{ url: 'redis://read.redis.my-service.com' }
],
useReplicas: true
});
Expand Down

0 comments on commit b7a49da

Please sign in to comment.