Skip to content

Commit 0a4186e

Browse files
committed
feat(redis): support readonly mode for cluster
1 parent 3e68925 commit 0a4186e

File tree

4 files changed

+38
-11
lines changed

4 files changed

+38
-11
lines changed

API.md

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Creates a Redis instance
6262
| [options.keyPrefix] | <code>string</code> | <code>&quot;&#x27;&#x27;&quot;</code> | The prefix to prepend to all keys in a command. ```javascript var redis = new Redis({ lazyConnect: true }); // No attempting to connect to the Redis server here. // Now let's connect to the Redis server redis.get('foo', function () { }); ``` |
6363
| [options.retryStrategy] | <code>function</code> | | See "Quick Start" section |
6464
| [options.reconnectOnError] | <code>function</code> | | See "Quick Start" section |
65+
| [options.readOnly] | <code>boolean</code> | <code>false</code> | Enable READONLY mode for the connection. Only available for cluster mode. |
6566

6667
**Example**
6768
```js

lib/redis.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ var ScanStream = require('./scan_stream');
7272
* ```
7373
* @param {function} [options.retryStrategy] - See "Quick Start" section
7474
* @param {function} [options.reconnectOnError] - See "Quick Start" section
75+
* @param {boolean} [options.readOnly=false] - Enable READONLY mode for the connection.
76+
* Only available for cluster mode.
7577
* @extends [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)
7678
* @extends Commander
7779
* @example
@@ -166,7 +168,8 @@ Redis.defaultOptions = {
166168
autoResendUnfulfilledCommands: true,
167169
lazyConnect: false,
168170
keyPrefix: '',
169-
reconnectOnError: null
171+
reconnectOnError: null,
172+
readOnly: false
170173
};
171174

172175
Redis.prototype.resetCommandQueue = function () {

lib/redis/event_handler.js

+5
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ exports.readyHandler = function (self) {
128128
self.client('setname', self.options.connectionName);
129129
}
130130

131+
if (self.options.readOnly) {
132+
debug('set the connection to readonly mode');
133+
self.readonly();
134+
}
135+
131136
if (self.prevCondition) {
132137
var condition = self.prevCondition;
133138
self.prevCondition = null;

test/functional/connection.js

+28-10
Original file line numberDiff line numberDiff line change
@@ -142,32 +142,50 @@ describe('connection', function () {
142142
describe('connectionName', function () {
143143
it('shoud name the connection if options.connectionName is not null', function (done) {
144144
var redis = new Redis({ connectionName: 'niceName' });
145-
redis.once('ready', function() {
146-
redis.client('getname', function(err, res) {
145+
redis.once('ready', function () {
146+
redis.client('getname', function (err, res) {
147147
expect(res).to.eql('niceName');
148148
done();
149149
});
150150
});
151151
redis.set('foo', 1);
152152
});
153153

154-
it('should set the name before any subscribe command if reconnected', function(done) {
154+
it('should set the name before any subscribe command if reconnected', function (done) {
155155
var redis = new Redis({ connectionName: 'niceName' });
156-
var pub = new Redis();
157156
redis.once('ready', function () {
158-
redis.subscribe('l', function() {
157+
redis.subscribe('l', function () {
159158
redis.disconnect(true);
160-
redis.unsubscribe('l', function() {
161-
redis.client('getname', function(err, res) {
162-
expect(res).to.eql('niceName');
163-
done();
164-
});
159+
redis.unsubscribe('l', function () {
160+
redis.client('getname', function (err, res) {
161+
expect(res).to.eql('niceName');
162+
done();
163+
});
165164
});
166165
});
167166
});
168167
});
169168
});
170169

170+
describe('readOnly', function () {
171+
it('shoud send readonly command before other commands', function (done) {
172+
var called = false;
173+
var redis = new Redis({ port: 30001, readOnly: true, showFriendlyErrorStack: true });
174+
var node = new MockServer(30001, function (argv) {
175+
if (argv[0] === 'readonly') {
176+
called = true;
177+
} else if (argv[0] === 'get' && argv[1] === 'foo') {
178+
expect(called).to.eql(true);
179+
redis.disconnect();
180+
node.disconnect(function () {
181+
done();
182+
});
183+
}
184+
});
185+
redis.get('foo').catch(function () {});
186+
});
187+
});
188+
171189
describe('autoResendUnfulfilledCommands', function () {
172190
it('should resend unfulfilled commands to the correct db when reconnected', function (done) {
173191
var redis = new Redis({ db: 3 });

0 commit comments

Comments
 (0)