1
1
import { parseURL } from '../utils'
2
2
import { EventEmitter } from 'events'
3
- import { noop , defaults } from '../utils/lodash'
3
+ import { noop , defaults , values } from '../utils/lodash'
4
+ import { IRedisOptions , getNodeKey } from './util'
4
5
5
6
const Redis = require ( '../redis' )
6
7
const debug = require ( '../utils/debug' ) ( 'ioredis:cluster:connectionPool' )
7
8
8
9
type NODE_TYPE = 'all' | 'master' | 'slave'
9
10
10
- interface IRedisOptions {
11
- [ key : string ] : any
12
- }
13
-
14
- interface IRedisOptionsWithKey extends IRedisOptions {
15
- key : string
16
- }
17
-
18
11
export default class ConnectionPool extends EventEmitter {
19
12
// master + slave = all
20
13
private nodes : { [ key in NODE_TYPE ] : { [ key : string ] : any } } = {
@@ -29,6 +22,10 @@ export default class ConnectionPool extends EventEmitter {
29
22
super ( )
30
23
}
31
24
25
+ public getNodes ( role : 'all' | 'master' | 'slave' = 'all' ) : any [ ] {
26
+ return values ( this . nodes [ role ] )
27
+ }
28
+
32
29
/**
33
30
* Find or create a connection to the node
34
31
*
@@ -37,33 +34,34 @@ export default class ConnectionPool extends EventEmitter {
37
34
* @returns {* }
38
35
* @memberof ConnectionPool
39
36
*/
40
- public findOrCreate ( node : IRedisOptions , readOnly : boolean = false ) : any {
41
- setKey ( node )
37
+ public findOrCreate ( node : IRedisOptions , readOnly : boolean = false ) : any {
38
+ fillDefaultOptions ( node )
39
+ const key = getNodeKey ( node )
42
40
readOnly = Boolean ( readOnly )
43
41
44
- if ( this . specifiedOptions [ node . key ] ) {
45
- Object . assign ( node , this . specifiedOptions [ node . key ] )
42
+ if ( this . specifiedOptions [ key ] ) {
43
+ Object . assign ( node , this . specifiedOptions [ key ] )
46
44
} else {
47
- this . specifiedOptions [ node . key ] = node
45
+ this . specifiedOptions [ key ] = node
48
46
}
49
47
50
48
let redis
51
- if ( this . nodes . all [ node . key ] ) {
52
- redis = this . nodes . all [ node . key ]
49
+ if ( this . nodes . all [ key ] ) {
50
+ redis = this . nodes . all [ key ]
53
51
if ( redis . options . readOnly !== readOnly ) {
54
52
redis . options . readOnly = readOnly
55
- debug ( 'Change role of %s to %s' , node . key , readOnly ? 'slave' : 'master' )
53
+ debug ( 'Change role of %s to %s' , key , readOnly ? 'slave' : 'master' )
56
54
redis [ readOnly ? 'readonly' : 'readwrite' ] ( ) . catch ( noop )
57
55
if ( readOnly ) {
58
- delete this . nodes . master [ node . key ]
59
- this . nodes . slave [ node . key ] = redis
56
+ delete this . nodes . master [ key ]
57
+ this . nodes . slave [ key ] = redis
60
58
} else {
61
- delete this . nodes . slave [ node . key ]
62
- this . nodes . master [ node . key ] = redis
59
+ delete this . nodes . slave [ key ]
60
+ this . nodes . master [ key ] = redis
63
61
}
64
62
}
65
63
} else {
66
- debug ( 'Connecting to %s as %s' , node . key , readOnly ? 'slave' : 'master' )
64
+ debug ( 'Connecting to %s as %s' , key , readOnly ? 'slave' : 'master' )
67
65
redis = new Redis ( defaults ( {
68
66
// Never try to reconnect when a node is lose,
69
67
// instead, waiting for a `MOVED` error and
@@ -75,23 +73,23 @@ export default class ConnectionPool extends EventEmitter {
75
73
enableOfflineQueue : true ,
76
74
readOnly : readOnly
77
75
} , node , this . redisOptions , { lazyConnect : true } ) )
78
- this . nodes . all [ node . key ] = redis
79
- this . nodes [ readOnly ? 'slave' : 'master' ] [ node . key ] = redis
76
+ this . nodes . all [ key ] = redis
77
+ this . nodes [ readOnly ? 'slave' : 'master' ] [ key ] = redis
80
78
81
79
redis . once ( 'end' , ( ) => {
82
- delete this . nodes . all [ node . key ]
83
- delete this . nodes . master [ node . key ]
84
- delete this . nodes . slave [ node . key ]
85
- this . emit ( '-node' , redis )
80
+ delete this . nodes . all [ key ]
81
+ delete this . nodes . master [ key ]
82
+ delete this . nodes . slave [ key ]
83
+ this . emit ( '-node' , redis , key )
86
84
if ( ! Object . keys ( this . nodes . all ) . length ) {
87
85
this . emit ( 'drain' )
88
86
}
89
87
} )
90
88
91
- this . emit ( '+node' , redis )
89
+ this . emit ( '+node' , redis , key )
92
90
93
91
redis . on ( 'error' , function ( error ) {
94
- this . emit ( 'nodeError' , error )
92
+ this . emit ( 'nodeError' , error , key )
95
93
} )
96
94
}
97
95
@@ -105,14 +103,15 @@ export default class ConnectionPool extends EventEmitter {
105
103
* @param {(Array<string | number | object>) } nodes
106
104
* @memberof ConnectionPool
107
105
*/
108
- public reset ( nodes : Array < string | number | object > ) : void {
106
+ public reset ( nodes : Array < string | number | object > ) : void {
107
+ debug ( 'Reset with %O' , nodes ) ;
109
108
const newNodes = { }
110
109
nodes . forEach ( ( node ) => {
111
- const options : { port ?: number | string , db ?: number , key ?: string } = { }
110
+ const options : IRedisOptions = { }
112
111
if ( typeof node === 'object' ) {
113
- defaults ( options , node )
112
+ Object . assign ( options , node )
114
113
} else if ( typeof node === 'string' ) {
115
- defaults ( options , parseURL ( node ) )
114
+ Object . assign ( options , parseURL ( node ) )
116
115
} else if ( typeof node === 'number' ) {
117
116
options . port = node
118
117
} else {
@@ -123,8 +122,8 @@ export default class ConnectionPool extends EventEmitter {
123
122
}
124
123
delete options . db
125
124
126
- setKey ( options )
127
- newNodes [ options . key ] = options
125
+ fillDefaultOptions ( options )
126
+ newNodes [ getNodeKey ( options ) ] = options
128
127
} , this )
129
128
130
129
Object . keys ( this . nodes . all ) . forEach ( ( key ) => {
@@ -140,15 +139,7 @@ export default class ConnectionPool extends EventEmitter {
140
139
}
141
140
}
142
141
143
- /**
144
- * Set key property
145
- *
146
- * @private
147
- */
148
- function setKey ( node : IRedisOptions ) : IRedisOptionsWithKey {
149
- node = node || { }
142
+ function fillDefaultOptions ( node : IRedisOptions ) : void {
150
143
node . port = node . port || 6379
151
144
node . host = node . host || '127.0.0.1'
152
- node . key = node . key || node . host + ':' + node . port
153
- return < IRedisOptionsWithKey > node
154
145
}
0 commit comments