Skip to content

Commit f0c600b

Browse files
authored
feat: Redis#connect() will be resolved when status is ready (#648)
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') }) ```
1 parent 7517a73 commit f0c600b

File tree

3 files changed

+66
-18
lines changed

3 files changed

+66
-18
lines changed

API.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* [Redis](#Redis) ⇐ <code>[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)</code>
1919
* [new Redis([port], [host], [options])](#new_Redis_new)
2020
* _instance_
21-
* [.connect([callback])](#Redis+connect) ⇒ <code>Promise</code>
21+
* [.connect([callback])](#Redis+connect) ⇒ <code>Promise.&lt;void&gt;</code>
2222
* [.disconnect()](#Redis+disconnect)
2323
* ~~[.end()](#Redis+end)~~
2424
* [.duplicate()](#Redis+duplicate)
@@ -68,7 +68,6 @@ Creates a Redis instance
6868
var Redis = require('ioredis');
6969

7070
var redis = new Redis();
71-
// or: var redis = Redis();
7271

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

83-
### redis.connect([callback]) ⇒ <code>Promise</code>
82+
### redis.connect([callback]) ⇒ <code>Promise.&lt;void&gt;</code>
8483
Create a connection to Redis.
85-
This method will be invoked automatically when creating a new Redis instance.
84+
This method will be invoked automatically when creating a new Redis instance
85+
unless `lazyConnect: true` is passed.
86+
87+
When calling this method manually, a Promise is returned, which will
88+
be resolved when the connection status is ready.
8689

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

239243
<a name="Cluster+connect"></a>

lib/redis.js

+19-13
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,13 @@ Redis.prototype.setStatus = function (status, arg) {
239239

240240
/**
241241
* Create a connection to Redis.
242-
* This method will be invoked automatically when creating a new Redis instance.
242+
* This method will be invoked automatically when creating a new Redis instance
243+
* unless `lazyConnect: true` is passed.
244+
*
245+
* When calling this method manually, a Promise is returned, which will
246+
* be resolved when the connection status is ready.
243247
* @param {function} [callback]
244-
* @return {Promise}
248+
* @return {Promise<void>}
245249
* @public
246250
*/
247251
Redis.prototype.connect = function (callback) {
@@ -253,9 +257,11 @@ Redis.prototype.connect = function (callback) {
253257
}
254258
this.setStatus('connecting');
255259

260+
const {options} = this;
261+
256262
this.condition = {
257-
select: this.options.db,
258-
auth: this.options.password,
263+
select: options.db,
264+
auth: options.password,
259265
subscriber: false
260266
};
261267

@@ -268,20 +274,20 @@ Redis.prototype.connect = function (callback) {
268274
_this.setStatus('end');
269275
return;
270276
}
271-
var CONNECT_EVENT = _this.options.tls ? 'secureConnect' : 'connect';
277+
var CONNECT_EVENT = options.tls ? 'secureConnect' : 'connect';
272278

273279
_this.stream = stream;
274-
if (typeof _this.options.keepAlive === 'number') {
275-
stream.setKeepAlive(true, _this.options.keepAlive);
280+
if (typeof options.keepAlive === 'number') {
281+
stream.setKeepAlive(true, options.keepAlive);
276282
}
277283

278284
stream.once(CONNECT_EVENT, eventHandler.connectHandler(_this));
279285
stream.once('error', eventHandler.errorHandler(_this));
280286
stream.once('close', eventHandler.closeHandler(_this));
281287
stream.on('data', eventHandler.dataHandler(_this));
282288

283-
if (_this.options.connectTimeout) {
284-
stream.setTimeout(_this.options.connectTimeout, function () {
289+
if (options.connectTimeout) {
290+
stream.setTimeout(options.connectTimeout, function () {
285291
stream.setTimeout(0);
286292
stream.destroy();
287293

@@ -296,19 +302,19 @@ Redis.prototype.connect = function (callback) {
296302
});
297303
}
298304

299-
if (_this.options.noDelay) {
305+
if (options.noDelay) {
300306
stream.setNoDelay(true);
301307
}
302308

303-
var connectionConnectHandler = function () {
309+
var connectionReadyHandler = function () {
304310
_this.removeListener('close', connectionCloseHandler);
305311
resolve();
306312
};
307313
var connectionCloseHandler = function () {
308-
_this.removeListener(CONNECT_EVENT, connectionConnectHandler);
314+
_this.removeListener('ready', connectionReadyHandler);
309315
reject(new Error(utils.CONNECTION_CLOSED_ERROR_MSG));
310316
};
311-
_this.once(CONNECT_EVENT, connectionConnectHandler);
317+
_this.once('ready', connectionReadyHandler);
312318
_this.once('close', connectionCloseHandler);
313319
}, function (type, err) {
314320
_this.silentEmit(type, err);

test/functional/connection.js

+39-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ describe('connection', function () {
9696

9797
it('should stop reconnecting when disconnected', function (done) {
9898
var redis = new Redis(8999, {
99-
retryStrategy: function () { return 0; }
99+
retryStrategy: function () {
100+
return 0;
101+
}
100102
});
101103

102104
redis.on('close', function () {
@@ -116,6 +118,42 @@ describe('connection', function () {
116118
done();
117119
});
118120
});
121+
122+
it('should resolve when the status become ready', function (done) {
123+
var redis = new Redis({ lazyConnect: true });
124+
redis.connect().then(function () {
125+
expect(redis.status).to.eql('ready');
126+
done();
127+
});
128+
});
129+
130+
it('should reject when closed (reconnecting)', function (done) {
131+
var redis = new Redis({
132+
port: 8989,
133+
lazyConnect: true,
134+
retryStrategy: function () {
135+
return 0;
136+
}
137+
});
138+
139+
redis.connect().catch(function () {
140+
expect(redis.status).to.eql('reconnecting');
141+
done();
142+
});
143+
});
144+
145+
it('should reject when closed (end)', function (done) {
146+
var redis = new Redis({
147+
port: 8989,
148+
lazyConnect: true,
149+
retryStrategy: false
150+
});
151+
152+
redis.connect().catch(function () {
153+
expect(redis.status).to.eql('end');
154+
done();
155+
});
156+
});
119157
});
120158

121159
describe('retryStrategy', function () {

0 commit comments

Comments
 (0)