@@ -32,6 +32,8 @@ function RedisSentinelClient(options) {
32
32
33
33
this . options . masterName = this . options . masterName || 'mymaster' ;
34
34
35
+ self . emitMasterErrors = false ;
36
+
35
37
// no socket support for now (b/c need multiple connections).
36
38
if ( options . port == null || options . host == null ) {
37
39
throw new Error ( "Sentinel client needs a host and port" ) ;
@@ -42,13 +44,30 @@ function RedisSentinelClient(options) {
42
44
throw new Error ( "Sentinel client takes only options to initialize" ) ;
43
45
}
44
46
45
- // this client will always be connected to the active master.
46
- // exposed publicly.
47
- // (initialized on reconnect())
48
- this . activeMasterClient = null ;
47
+ // this client will always be connected to the active master
48
+ self . debug ( "Creating new dummy master" ) ;
49
+ // Make new client
50
+ self . activeMasterClient = new RedisSingleClient . createClient ( 9999 , '127.0.0.1' ,
51
+ {
52
+ sentinel : false ,
53
+ disable_flush : true // Disables flush_and_error, to preserve queue
54
+ }
55
+ ) ;
49
56
50
- // used for swaps
51
- this . oldMasterClient = null ;
57
+ // pass up errors
58
+ // @todo emit a separate 'master error' event?
59
+ self . activeMasterClient . on ( 'error' , function ( error ) {
60
+ if ( self . emitMasterErrors ) {
61
+ error . message = self . myName + " master error: " + error . message ;
62
+ self . onError . call ( self , error ) ;
63
+ }
64
+ } ) ;
65
+
66
+ // pass up messages
67
+ self . activeMasterClient . on ( 'message' , function ( channel , message ) {
68
+ self . emit ( 'message' , channel , message ) ;
69
+ } ) ;
70
+
52
71
53
72
// used for logging & errors
54
73
this . myName = 'sentinel-' + this . options . host + ':' + this . options . port + '-' + this . options . masterName ;
@@ -125,6 +144,12 @@ function RedisSentinelClient(options) {
125
144
self . emit ( 'sentinel message' , msg ) ;
126
145
127
146
switch ( msg ) {
147
+ case '+sdown' :
148
+ self . debug ( 'Down detected' ) ;
149
+ self . emit ( 'down-start' ) ;
150
+ self . emitMasterErrors = false ;
151
+ break ;
152
+
128
153
case '+failover-triggered' :
129
154
self . debug ( 'Failover detected' ) ;
130
155
self . emit ( 'failover-start' ) ;
@@ -178,52 +203,26 @@ RedisSentinelClient.prototype.reconnect = function reconnect(onReconnectCallback
178
203
return ;
179
204
}
180
205
206
+
181
207
self . debug ( "Changing master from " +
182
208
( self . activeMasterClient ? self . activeMasterClient . host + ":" + self . activeMasterClient . port : "[none]" ) +
183
209
" to " + newMaster . host + ":" + newMaster . port ) ;
184
210
185
- // "Note that this does not wait until all replies have been parsed.
186
- // If you want to exit cleanly, call client.quit()"
187
- // @review
188
-
189
- // we don't want to queue commands. so push aside the old one, kill it on the side,
190
- // and simultaneously swap in a new one.
191
- // @review does this work?
192
- self . oldMasterClient = self . activeMasterClient ;
211
+ // reconfigure it
212
+ self . activeMasterClient . host = newMaster . host ;
213
+ self . activeMasterClient . port = newMaster . port ;
193
214
194
- // note, old client will be null on 1st connect
195
- if ( self . oldMasterClient ) {
196
- self . debug ( 'old master was on ' + self . oldMasterClient . host + ':' + self . oldMasterClient . port ) ;
197
-
198
- // @check if this fn ends before end is called, will event still fire?
199
- self . oldMasterClient . once ( 'end' , function ( ) {
200
- self . debug ( "Old master ended" ) ;
201
- self . emit ( 'disconnected' ) ;
202
- } ) ;
203
- }
215
+ // reconnect it
216
+ self . activeMasterClient . forceReconnectionAttempt ( ) ;
204
217
205
- // new master client
206
- // should queue all subsequent commands internally.
207
- // but any commands still queued in the old master, will be lost.
208
- self . activeMasterClient = new RedisSingleClient . createClient ( newMaster . port , newMaster . host , { sentinel : false } ) ;
209
218
210
- // kill the old one
211
- if ( self . oldMasterClient ) {
212
- self . oldMasterClient . end ( ) ;
213
- }
214
-
215
- // pass up errors, (& other events?)
216
- // @todo emit a separate 'master error' event?
217
- self . activeMasterClient . on ( 'error' , function ( error ) {
218
- error . message = self . myName + " master error: " + error . message ;
219
- self . onError . call ( self , error ) ;
220
- } ) ;
221
219
222
220
// @todo use no_ready_check = true? then change this 'ready' to 'connect'
223
221
224
222
// backwards-compat. w/RedisClient
225
223
self . activeMasterClient . once ( 'connect' , function ( ) {
226
224
self . emit ( 'connect' ) ;
225
+ self . emitMasterErrors = true ;
227
226
} ) ;
228
227
229
228
self . activeMasterClient . once ( 'ready' , function ( ) {
0 commit comments