Skip to content

Commit

Permalink
feat: Redis#connect() will be resolved when status is ready (#648)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
`Redis#connect()` will be resolved when status is ready
instead of `connect`:

```
const redis = new Redis({ lazyConnect: true })
redis.connect().then(() => {
  assert(redis.status === 'ready')
})
```
  • Loading branch information
luin authored Jun 30, 2018
1 parent 7517a73 commit f0c600b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 18 deletions.
12 changes: 8 additions & 4 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* [Redis](#Redis) ⇐ <code>[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)</code>
* [new Redis([port], [host], [options])](#new_Redis_new)
* _instance_
* [.connect([callback])](#Redis+connect) ⇒ <code>Promise</code>
* [.connect([callback])](#Redis+connect) ⇒ <code>Promise.&lt;void&gt;</code>
* [.disconnect()](#Redis+disconnect)
* ~~[.end()](#Redis+end)~~
* [.duplicate()](#Redis+duplicate)
Expand Down Expand Up @@ -68,7 +68,6 @@ Creates a Redis instance
var Redis = require('ioredis');

var redis = new Redis();
// or: var redis = Redis();

var redisOnPort6380 = new Redis(6380);
var anotherRedis = new Redis(6380, '192.168.100.1');
Expand All @@ -80,9 +79,13 @@ var authedRedis = new Redis(6380, '192.168.100.1', { password: 'password' });
```
<a name="Redis+connect"></a>

### redis.connect([callback]) ⇒ <code>Promise</code>
### redis.connect([callback]) ⇒ <code>Promise.&lt;void&gt;</code>
Create a connection to Redis.
This method will be invoked automatically when creating a new Redis instance.
This method will be invoked automatically when creating a new Redis instance
unless `lazyConnect: true` is passed.

When calling this method manually, a Promise is returned, which will
be resolved when the connection status is ready.

**Kind**: instance method of [<code>Redis</code>](#Redis)
**Access**: public
Expand Down Expand Up @@ -234,6 +237,7 @@ Creates a Redis Cluster instance
| [options.retryDelayOnClusterDown] | <code>number</code> | <code>100</code> | When a CLUSTERDOWN error is received, client will retry if `retryDelayOnClusterDown` is valid delay time. |
| [options.retryDelayOnTryAgain] | <code>number</code> | <code>100</code> | When a TRYAGAIN error is received, client will retry if `retryDelayOnTryAgain` is valid delay time. |
| [options.slotsRefreshTimeout] | <code>number</code> | <code>1000</code> | The milliseconds before a timeout occurs while refreshing slots from the cluster. |
| [options.slotsRefreshInterval] | <code>number</code> | <code>5000</code> | The milliseconds between every automatic slots refresh. |
| [options.redisOptions] | <code>Object</code> | | Passed to the constructor of `Redis`. |

<a name="Cluster+connect"></a>
Expand Down
32 changes: 19 additions & 13 deletions lib/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,13 @@ Redis.prototype.setStatus = function (status, arg) {

/**
* Create a connection to Redis.
* This method will be invoked automatically when creating a new Redis instance.
* This method will be invoked automatically when creating a new Redis instance
* unless `lazyConnect: true` is passed.
*
* When calling this method manually, a Promise is returned, which will
* be resolved when the connection status is ready.
* @param {function} [callback]
* @return {Promise}
* @return {Promise<void>}
* @public
*/
Redis.prototype.connect = function (callback) {
Expand All @@ -253,9 +257,11 @@ Redis.prototype.connect = function (callback) {
}
this.setStatus('connecting');

const {options} = this;

this.condition = {
select: this.options.db,
auth: this.options.password,
select: options.db,
auth: options.password,
subscriber: false
};

Expand All @@ -268,20 +274,20 @@ Redis.prototype.connect = function (callback) {
_this.setStatus('end');
return;
}
var CONNECT_EVENT = _this.options.tls ? 'secureConnect' : 'connect';
var CONNECT_EVENT = options.tls ? 'secureConnect' : 'connect';

_this.stream = stream;
if (typeof _this.options.keepAlive === 'number') {
stream.setKeepAlive(true, _this.options.keepAlive);
if (typeof options.keepAlive === 'number') {
stream.setKeepAlive(true, options.keepAlive);
}

stream.once(CONNECT_EVENT, eventHandler.connectHandler(_this));
stream.once('error', eventHandler.errorHandler(_this));
stream.once('close', eventHandler.closeHandler(_this));
stream.on('data', eventHandler.dataHandler(_this));

if (_this.options.connectTimeout) {
stream.setTimeout(_this.options.connectTimeout, function () {
if (options.connectTimeout) {
stream.setTimeout(options.connectTimeout, function () {
stream.setTimeout(0);
stream.destroy();

Expand All @@ -296,19 +302,19 @@ Redis.prototype.connect = function (callback) {
});
}

if (_this.options.noDelay) {
if (options.noDelay) {
stream.setNoDelay(true);
}

var connectionConnectHandler = function () {
var connectionReadyHandler = function () {
_this.removeListener('close', connectionCloseHandler);
resolve();
};
var connectionCloseHandler = function () {
_this.removeListener(CONNECT_EVENT, connectionConnectHandler);
_this.removeListener('ready', connectionReadyHandler);
reject(new Error(utils.CONNECTION_CLOSED_ERROR_MSG));
};
_this.once(CONNECT_EVENT, connectionConnectHandler);
_this.once('ready', connectionReadyHandler);
_this.once('close', connectionCloseHandler);
}, function (type, err) {
_this.silentEmit(type, err);
Expand Down
40 changes: 39 additions & 1 deletion test/functional/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ describe('connection', function () {

it('should stop reconnecting when disconnected', function (done) {
var redis = new Redis(8999, {
retryStrategy: function () { return 0; }
retryStrategy: function () {
return 0;
}
});

redis.on('close', function () {
Expand All @@ -116,6 +118,42 @@ describe('connection', function () {
done();
});
});

it('should resolve when the status become ready', function (done) {
var redis = new Redis({ lazyConnect: true });
redis.connect().then(function () {
expect(redis.status).to.eql('ready');
done();
});
});

it('should reject when closed (reconnecting)', function (done) {
var redis = new Redis({
port: 8989,
lazyConnect: true,
retryStrategy: function () {
return 0;
}
});

redis.connect().catch(function () {
expect(redis.status).to.eql('reconnecting');
done();
});
});

it('should reject when closed (end)', function (done) {
var redis = new Redis({
port: 8989,
lazyConnect: true,
retryStrategy: false
});

redis.connect().catch(function () {
expect(redis.status).to.eql('end');
done();
});
});
});

describe('retryStrategy', function () {
Expand Down

0 comments on commit f0c600b

Please sign in to comment.