@@ -62,6 +62,7 @@ class Client extends EventEmitter {
62
62
this . host = this . connectionParameters . host
63
63
this . loadBalance = this . connectionParameters . loadBalance
64
64
this . topologyKeys = this . connectionParameters . topologyKeys
65
+ this . ybServersRefreshInterval = this . connectionParameters . ybServersRefreshInterval
65
66
this . connectionString = config
66
67
// "hiding" the password so it doesn't show up in stack traces
67
68
// or if the client is console.logged
@@ -127,12 +128,8 @@ class Client extends EventEmitter {
127
128
static hostServerInfo = new Map ( )
128
129
// Boolean to check if public IP needs to be used or not
129
130
static usePublic = false
130
- // Set of topology Keys provided in URL
131
- static topologyKeySet = new Set ( )
132
- // time to refresh the ServerMetaData
133
- static REFRESING_TIME = 300 // secs
134
- // Boolean to Refresh ServerMetaData manually (for testing purpose).
135
- static doHardRefresh = false
131
+ // Map of topology Keys provided in URL
132
+ static topologyKeyMap = new Map ( )
136
133
137
134
_errorAllQueries ( err ) {
138
135
const enqueueError = ( query ) => {
@@ -156,32 +153,56 @@ class Client extends EventEmitter {
156
153
}
157
154
let minConnectionCount = Number . MAX_VALUE
158
155
let leastLoadedHosts = [ ]
159
- let hosts = hostsList . keys ( )
160
- for ( let value of hosts ) {
161
- let host = value
162
- if ( this . connectionParameters . topologyKeys !== '' ) {
156
+ for ( var i = 1 ; i <= Client . topologyKeyMap . size ; i ++ ) {
157
+ let hosts = hostsList . keys ( )
158
+ for ( let value of hosts ) {
159
+ let host = value
163
160
let placementInfoOfHost
164
- if ( ! this . checkConnectionMapEmpty ( ) ) {
161
+ if ( Client . hostServerInfo . has ( host ) ) {
165
162
placementInfoOfHost = Client . hostServerInfo . get ( host ) . placementInfo
166
- } else {
163
+ } else {
167
164
placementInfoOfHost = hostsList . get ( host ) . placementInfo
168
165
}
169
- if ( ! Client . topologyKeySet . has ( placementInfoOfHost ) ) {
166
+ var toCheckStar = placementInfoOfHost . split ( '.' )
167
+ var StarplacementInfoOfHost = toCheckStar [ 0 ] + "." + toCheckStar [ 1 ] + ".*"
168
+ if ( ! Client . topologyKeyMap . get ( i ) . includes ( placementInfoOfHost ) && ! Client . topologyKeyMap . get ( i ) . includes ( StarplacementInfoOfHost ) ) {
170
169
continue
171
170
}
171
+ let hostCount
172
+ if ( typeof hostsList . get ( host ) === 'object' ) {
173
+ hostCount = 0
174
+ } else {
175
+ hostCount = hostsList . get ( host )
176
+ }
177
+ if ( minConnectionCount > hostCount ) {
178
+ leastLoadedHosts = [ ]
179
+ minConnectionCount = hostCount
180
+ leastLoadedHosts . push ( host )
181
+ } else if ( minConnectionCount === hostCount ) {
182
+ leastLoadedHosts . push ( host )
183
+ }
172
184
}
173
- let hostCount
174
- if ( typeof hostsList . get ( host ) === 'object' ) {
175
- hostCount = 0
176
- } else {
177
- hostCount = hostsList . get ( host )
185
+ if ( leastLoadedHosts . length != 0 ) {
186
+ break
178
187
}
179
- if ( minConnectionCount > hostCount ) {
180
- leastLoadedHosts = [ ]
181
- minConnectionCount = hostCount
182
- leastLoadedHosts . push ( host )
183
- } else if ( minConnectionCount === hostCount ) {
184
- leastLoadedHosts . push ( host )
188
+ }
189
+
190
+ if ( leastLoadedHosts . length === 0 ) {
191
+ let hosts = hostsList . keys ( )
192
+ for ( let value of hosts ) {
193
+ let hostCount
194
+ if ( typeof hostsList . get ( value ) === 'object' ) {
195
+ hostCount = 0
196
+ } else {
197
+ hostCount = hostsList . get ( value )
198
+ }
199
+ if ( minConnectionCount > hostCount ) {
200
+ leastLoadedHosts = [ ]
201
+ minConnectionCount = hostCount
202
+ leastLoadedHosts . push ( value )
203
+ } else if ( minConnectionCount === hostCount ) {
204
+ leastLoadedHosts . push ( value )
205
+ }
185
206
}
186
207
}
187
208
if ( leastLoadedHosts . length === 0 ) {
@@ -193,11 +214,25 @@ class Client extends EventEmitter {
193
214
}
194
215
195
216
isValidKey ( key ) {
196
- var keyParts = key . split ( '.' )
217
+ var zones = key . split ( ':' )
218
+ if ( zones . length == 0 || zones . length > 2 ) {
219
+ return false
220
+ }
221
+ var keyParts = zones [ 0 ] . split ( '.' )
197
222
if ( keyParts . length !== 3 ) {
198
223
return false
199
224
}
200
- return Client . placementInfoHostMap . has ( key )
225
+ if ( zones [ 1 ] == undefined ) {
226
+ zones [ 1 ] = '1'
227
+ }
228
+ zones [ 1 ] = Number ( zones [ 1 ] )
229
+ if ( zones [ 1 ] < 1 || zones [ 1 ] > 10 || isNaN ( zones [ 1 ] ) || ! Number . isInteger ( zones [ 1 ] ) ) {
230
+ return false
231
+ }
232
+ if ( keyParts [ 2 ] != "*" ) {
233
+ return Client . placementInfoHostMap . has ( zones [ 0 ] )
234
+ }
235
+ return true
201
236
}
202
237
203
238
incrementConnectionCount ( ) {
@@ -249,7 +284,7 @@ class Client extends EventEmitter {
249
284
} , this . _connectionTimeoutMillis )
250
285
}
251
286
if ( this . connectionParameters . loadBalance ) {
252
- if ( ! this . checkConnectionMapEmpty ( ) && Client . hostServerInfo . size ) {
287
+ if ( Client . connectionMap . size && Client . hostServerInfo . size ) {
253
288
this . host = this . getLeastLoadedServer ( Client . connectionMap )
254
289
this . port = Client . hostServerInfo . get ( this . host ) . port
255
290
} else if ( Client . failedHosts . size ) {
@@ -442,12 +477,23 @@ class Client extends EventEmitter {
442
477
} )
443
478
}
444
479
445
- createTopologyKeySet ( ) {
480
+ createTopologyKeyMap ( ) {
446
481
var seperatedKeys = this . connectionParameters . topologyKeys . split ( ',' )
447
482
for ( let idx = 0 ; idx < seperatedKeys . length ; idx ++ ) {
448
483
let key = seperatedKeys [ idx ]
449
484
if ( this . isValidKey ( key ) ) {
450
- Client . topologyKeySet . add ( key )
485
+ var zones = key . split ( ':' )
486
+ if ( zones [ 1 ] == undefined ) {
487
+ zones [ 1 ] = '1'
488
+ }
489
+ zones [ 1 ] = parseInt ( zones [ 1 ] )
490
+ if ( Client . topologyKeyMap . has ( zones [ 1 ] ) ) {
491
+ let currentzones = Client . topologyKeyMap . get ( zones [ 1 ] )
492
+ currentzones . push ( zones [ 0 ] )
493
+ Client . topologyKeyMap . set ( zones [ 1 ] , currentzones )
494
+ } else {
495
+ Client . topologyKeyMap . set ( zones [ 1 ] , [ zones [ 0 ] ] )
496
+ }
451
497
} else {
452
498
throw new Error ( 'Bad Topology Key found - ' + key )
453
499
}
@@ -459,22 +505,8 @@ class Client extends EventEmitter {
459
505
Client . lastTimeMetaDataFetched = new Date ( ) . getTime ( ) / 1000
460
506
this . createConnectionMap ( data )
461
507
if ( this . connectionParameters . topologyKeys !== '' ) {
462
- this . createTopologyKeySet ( )
463
- }
464
- }
465
-
466
- checkConnectionMapEmpty ( ) {
467
- if ( this . connectionParameters . topologyKeys === '' ) {
468
- return Client . connectionMap . size === 0
508
+ this . createTopologyKeyMap ( )
469
509
}
470
- let hosts = Client . connectionMap . keys ( )
471
- for ( let value of hosts ) {
472
- let placementInfo = Client . hostServerInfo . get ( value ) . placementInfo
473
- if ( Client . topologyKeySet . has ( placementInfo ) ) {
474
- return false
475
- }
476
- }
477
- return true
478
510
}
479
511
480
512
nowConnect ( callback ) {
@@ -490,27 +522,6 @@ class Client extends EventEmitter {
490
522
} else if ( Client . failedHosts . has ( this . host ) ) {
491
523
Client . failedHosts . delete ( this . host )
492
524
}
493
- if ( this . checkConnectionMapEmpty ( ) && Client . failedHosts . size === 0 ) {
494
- lock . release ( )
495
- // try with url host and mark that connection type as non-loadBalanced
496
- this . host = this . urlHost
497
- this . connectionParameters . host = this . host
498
- this . connectionParameters . loadBalance = false
499
- this . connection =
500
- this . config . connection ||
501
- new Connection ( {
502
- stream : this . config . stream ,
503
- ssl : this . connectionParameters . ssl ,
504
- keepAlive : this . config . keepAlive || false ,
505
- keepAliveInitialDelayMillis : this . config . keepAliveInitialDelayMillis || 0 ,
506
- encoding : this . connectionParameters . client_encoding || 'utf8' ,
507
- } )
508
- this . _connecting = false
509
- Client . hostServerInfo . clear ( )
510
- Client . connectionMap . clear ( )
511
- this . connect ( callback )
512
- return
513
- }
514
525
lock . release ( )
515
526
this . connect ( callback )
516
527
} else {
@@ -543,26 +554,6 @@ class Client extends EventEmitter {
543
554
} else if ( Client . failedHosts . has ( this . host ) ) {
544
555
Client . failedHosts . delete ( this . host )
545
556
}
546
- if ( this . checkConnectionMapEmpty ( ) && Client . failedHosts . size === 0 ) {
547
- lock . release ( )
548
- this . host = this . urlHost
549
- this . connectionParameters . host = this . host
550
- this . connectionParameters . loadBalance = false
551
- this . connection =
552
- this . config . connection ||
553
- new Connection ( {
554
- stream : this . config . stream ,
555
- ssl : this . connectionParameters . ssl ,
556
- keepAlive : this . config . keepAlive || false ,
557
- keepAliveInitialDelayMillis : this . config . keepAliveInitialDelayMillis || 0 ,
558
- encoding : this . connectionParameters . client_encoding || 'utf8' ,
559
- } )
560
- this . _connecting = false
561
- Client . hostServerInfo . clear ( )
562
- Client . connectionMap . clear ( )
563
- this . connect ( callback )
564
- return
565
- }
566
557
lock . release ( )
567
558
this . connect ( callback )
568
559
} else {
@@ -605,7 +596,7 @@ class Client extends EventEmitter {
605
596
isRefreshRequired ( ) {
606
597
let currentTime = new Date ( ) . getTime ( ) / 1000
607
598
let diff = Math . floor ( currentTime - Client . lastTimeMetaDataFetched )
608
- return diff >= Client . REFRESING_TIME
599
+ return diff >= this . connectionParameters . ybServersRefreshInterval
609
600
}
610
601
611
602
connect ( callback ) {
@@ -636,7 +627,7 @@ class Client extends EventEmitter {
636
627
return this . nowConnect ( callback )
637
628
} )
638
629
} else {
639
- if ( this . isRefreshRequired ( ) || Client . doHardRefresh ) {
630
+ if ( this . isRefreshRequired ( ) ) {
640
631
this . getServersInfo ( )
641
632
. then ( ( res ) => {
642
633
this . updateMetaData ( res . rows )
0 commit comments