@@ -6,7 +6,8 @@ import {ITcpConnectionOptions, isIIpcConnectionOptions} from '../StandaloneConne
6
6
import SentinelIterator from './SentinelIterator'
7
7
import { ISentinelAddress } from './types' ;
8
8
import AbstractConnector , { ErrorEmitter } from '../AbstractConnector'
9
- import { NetStream } from '../../types'
9
+ import { NetStream , CallbackFunction } from '../../types' ;
10
+ import * as PromiseContainer from '../../promiseContainer' ;
10
11
import Redis from '../../redis'
11
12
12
13
const debug = Debug ( 'SentinelConnector' )
@@ -17,12 +18,13 @@ interface IAddressFromResponse {
17
18
flags ?: string
18
19
}
19
20
20
- type NodeCallback < T = void > = ( err : Error | null , result ?: T ) => void
21
21
type PreferredSlaves =
22
22
( ( slaves : Array < IAddressFromResponse > ) => IAddressFromResponse | null ) |
23
23
Array < { port : string , ip : string , prio ?: number } > |
24
24
{ port : string , ip : string , prio ?: number }
25
25
26
+ export { ISentinelAddress , SentinelIterator } ;
27
+
26
28
export interface ISentinelConnectionOptions extends ITcpConnectionOptions {
27
29
role : 'master' | 'slave'
28
30
name : string
@@ -39,12 +41,12 @@ export interface ISentinelConnectionOptions extends ITcpConnectionOptions {
39
41
40
42
export default class SentinelConnector extends AbstractConnector {
41
43
private retryAttempts : number
42
- private sentinelIterator : SentinelIterator
44
+ protected sentinelIterator : SentinelIterator
43
45
44
46
constructor ( protected options : ISentinelConnectionOptions ) {
45
47
super ( )
46
48
47
- if ( this . options . sentinels . length === 0 ) {
49
+ if ( ! this . options . sentinels . length ) {
48
50
throw new Error ( 'Requires at least one sentinel to connect to.' )
49
51
}
50
52
if ( ! this . options . name ) {
@@ -68,19 +70,20 @@ export default class SentinelConnector extends AbstractConnector {
68
70
return roleMatches
69
71
}
70
72
71
- public connect ( callback : NodeCallback < NetStream > , eventEmitter : ErrorEmitter ) : void {
73
+ public connect ( eventEmitter : ErrorEmitter ) : Promise < NetStream > {
72
74
this . connecting = true
73
75
this . retryAttempts = 0
74
76
75
77
let lastError
76
- const _this = this
77
- connectToNext ( )
78
-
79
- function connectToNext ( ) {
80
- if ( ! _this . sentinelIterator . hasNext ( ) ) {
81
- _this . sentinelIterator . reset ( false )
82
- const retryDelay = typeof _this . options . sentinelRetryStrategy === 'function'
83
- ? _this . options . sentinelRetryStrategy ( ++ _this . retryAttempts )
78
+ const _Promise = PromiseContainer . get ( ) ;
79
+
80
+ const connectToNext = ( ) => new _Promise < NetStream > ( ( resolve , reject ) => {
81
+ const endpoint = this . sentinelIterator . next ( ) ;
82
+
83
+ if ( endpoint . done ) {
84
+ this . sentinelIterator . reset ( false )
85
+ const retryDelay = typeof this . options . sentinelRetryStrategy === 'function'
86
+ ? this . options . sentinelRetryStrategy ( ++ this . retryAttempts )
84
87
: null
85
88
86
89
let errorMsg = typeof retryDelay !== 'number'
@@ -95,32 +98,33 @@ export default class SentinelConnector extends AbstractConnector {
95
98
96
99
const error = new Error ( errorMsg )
97
100
if ( typeof retryDelay === 'number' ) {
98
- setTimeout ( connectToNext , retryDelay )
101
+ setTimeout ( ( ) => {
102
+ resolve ( connectToNext ( ) ) ;
103
+ } , retryDelay )
99
104
eventEmitter ( 'error' , error )
100
105
} else {
101
- callback ( error )
106
+ reject ( error )
102
107
}
103
108
return
104
109
}
105
110
106
- const endpoint = _this . sentinelIterator . next ( )
107
- _this . resolve ( endpoint , function ( err , resolved ) {
108
- if ( ! _this . connecting ) {
109
- callback ( new Error ( CONNECTION_CLOSED_ERROR_MSG ) )
111
+ this . resolve ( endpoint . value , ( err , resolved ) => {
112
+ if ( ! this . connecting ) {
113
+ reject ( new Error ( CONNECTION_CLOSED_ERROR_MSG ) )
110
114
return
111
115
}
112
116
if ( resolved ) {
113
117
debug ( 'resolved: %s:%s' , resolved . host , resolved . port )
114
- if ( _this . options . enableTLSForSentinelMode && _this . options . tls ) {
115
- Object . assign ( resolved , _this . options . tls )
116
- _this . stream = createTLSConnection ( resolved )
118
+ if ( this . options . enableTLSForSentinelMode && this . options . tls ) {
119
+ Object . assign ( resolved , this . options . tls )
120
+ this . stream = createTLSConnection ( resolved )
117
121
} else {
118
- _this . stream = createConnection ( resolved )
122
+ this . stream = createConnection ( resolved )
119
123
}
120
- _this . sentinelIterator . reset ( true )
121
- callback ( null , _this . stream )
124
+ this . sentinelIterator . reset ( true )
125
+ resolve ( this . stream )
122
126
} else {
123
- const endpointAddress = endpoint . host + ':' + endpoint . port
127
+ const endpointAddress = endpoint . value . host + ':' + endpoint . value . port
124
128
const errorMsg = err
125
129
? 'failed to connect to sentinel ' + endpointAddress + ' because ' + err . message
126
130
: 'connected to sentinel ' + endpointAddress + ' successfully, but got an invalid reply: ' + resolved
@@ -132,13 +136,15 @@ export default class SentinelConnector extends AbstractConnector {
132
136
if ( err ) {
133
137
lastError = err
134
138
}
135
- connectToNext ( )
139
+ resolve ( connectToNext ( ) )
136
140
}
137
141
} )
138
- }
142
+ } ) ;
143
+
144
+ return connectToNext ( ) ;
139
145
}
140
146
141
- private updateSentinels ( client , callback : NodeCallback ) : void {
147
+ private updateSentinels ( client , callback : CallbackFunction ) : void {
142
148
143
149
if ( ! this . options . updateSentinels ) {
144
150
return callback ( null )
@@ -167,7 +173,7 @@ export default class SentinelConnector extends AbstractConnector {
167
173
} )
168
174
}
169
175
170
- private resolveMaster ( client , callback : NodeCallback < ITcpConnectionOptions > ) : void {
176
+ private resolveMaster ( client , callback : CallbackFunction < ITcpConnectionOptions > ) : void {
171
177
client . sentinel ( 'get-master-addr-by-name' , this . options . name , ( err , result ) => {
172
178
if ( err ) {
173
179
client . disconnect ( )
@@ -186,7 +192,7 @@ export default class SentinelConnector extends AbstractConnector {
186
192
} )
187
193
}
188
194
189
- private resolveSlave ( client , callback : NodeCallback < ITcpConnectionOptions | null > ) : void {
195
+ private resolveSlave ( client , callback : CallbackFunction < ITcpConnectionOptions | null > ) : void {
190
196
client . sentinel ( 'slaves' , this . options . name , ( err , result ) => {
191
197
client . disconnect ( )
192
198
if ( err ) {
@@ -214,7 +220,7 @@ export default class SentinelConnector extends AbstractConnector {
214
220
return this . options . natMap [ `${ item . host } :${ item . port } ` ] || item
215
221
}
216
222
217
- private resolve ( endpoint , callback : NodeCallback < ITcpConnectionOptions > ) : void {
223
+ private resolve ( endpoint , callback : CallbackFunction < ITcpConnectionOptions > ) : void {
218
224
var client = new Redis ( {
219
225
port : endpoint . port || 26379 ,
220
226
host : endpoint . host ,
0 commit comments