@@ -116,7 +116,7 @@ class Driver {
116
116
}
117
117
118
118
_createSession ( conn ) {
119
- return new Session ( conn , ( cb ) => {
119
+ return new Session ( new Promise ( ( resolve , reject ) => resolve ( conn ) ) , ( cb ) => {
120
120
// This gets called on Session#close(), and is where we return
121
121
// the pooled 'connection' instance.
122
122
@@ -204,6 +204,47 @@ class RoundRobinArray {
204
204
}
205
205
206
206
let GET_SERVERS = "CALL dbms.cluster.routing.getServers" ;
207
+
208
+ class ClusterView {
209
+ constructor ( expires , routers , readers , writers ) {
210
+ this . expires = expires ;
211
+ this . routers = routers ;
212
+ this . readers = readers ;
213
+ this . routers = writers ;
214
+ }
215
+ }
216
+
217
+ function newClusterView ( session ) {
218
+ return session . run ( GET_SERVERS )
219
+ . then ( ( res ) => {
220
+ session . close ( ) ;
221
+ let record = res . records [ 0 ] ;
222
+ //Note we are loosing precision here but we are not
223
+ //terribly worried since it is only
224
+ //for dates more than 140000 years into the future.
225
+ let expires = record . get ( 'ttl' ) . toNumber ( ) ;
226
+ let servers = record . get ( 'servers' ) ;
227
+ let routers = new RoundRobinArray ( ) ;
228
+ let readers = new RoundRobinArray ( ) ;
229
+ let writers = new RoundRobinArray ( ) ;
230
+ for ( let i = 0 ; i <= servers . length ; i ++ ) {
231
+ let server = servers [ i ] ;
232
+
233
+ let role = server [ 'role' ] ;
234
+ let addresses = server [ 'addresses' ] ;
235
+ if ( role === 'ROUTE' ) {
236
+ routers . pushAll ( addresses ) ;
237
+ } else if ( role === 'WRITE' ) {
238
+ writers . pushAll ( addresses ) ;
239
+ } else if ( role === 'READ' ) {
240
+ readers . pushAll ( addresses ) ;
241
+ }
242
+ }
243
+
244
+ return new ClusterView ( expires , routers , readers , writers ) ;
245
+ } ) ;
246
+ }
247
+
207
248
class RoutingDriver extends Driver {
208
249
209
250
constructor ( url , userAgent = 'neo4j-javascript/0.0' , token = { } , config = { } ) {
@@ -213,15 +254,25 @@ class RoutingDriver extends Driver {
213
254
this . _readers = new RoundRobinArray ( ) ;
214
255
this . _writers = new RoundRobinArray ( ) ;
215
256
this . _expires = Date . now ( ) ;
216
- this . _checkServers ( ) ;
217
257
}
218
258
219
- _checkServers ( ) {
259
+ //TODO make nice, expose constants?
260
+ session ( mode ) {
261
+ //Check so that we have servers available
262
+ this . _checkServers ( ) . then ( ( ) => {
263
+ let conn = this . _acquireConnection ( mode ) ;
264
+ return this . _createSession ( conn ) ;
265
+ } ) ;
266
+ }
267
+
268
+ async _checkServers ( ) {
220
269
if ( this . _expires < Date . now ( ) ||
221
270
this . _routers . empty ( ) ||
222
271
this . _readers . empty ( ) ||
223
272
this . _writers . empty ( ) ) {
224
- this . _callServers ( ) ;
273
+ return await this . _callServers ( ) ;
274
+ } else {
275
+ return new Promise ( ( resolve , reject ) => resolve ( false ) ) ;
225
276
}
226
277
}
227
278
@@ -239,16 +290,19 @@ class RoutingDriver extends Driver {
239
290
let url = this . _routers . hop ( ) ;
240
291
try {
241
292
let res = await this . _call ( url ) ;
293
+ console . log ( "got result" ) ;
242
294
if ( res . records . length != 1 ) continue ;
243
295
let record = res . records [ 0 ] ;
244
296
//Note we are loosing precision here but we are not
245
297
//terribly worried since it is only
246
298
//for dates more than 140000 years into the future.
247
299
this . _expires += record . get ( 'ttl' ) . toNumber ( ) ;
248
300
let servers = record . get ( 'servers' ) ;
301
+ console . log ( servers ) ;
249
302
for ( let i = 0 ; i <= servers . length ; i ++ ) {
250
303
let server = servers [ i ] ;
251
- seen . delete ( server ) ;
304
+ seen . remove ( server ) ;
305
+
252
306
let role = server [ 'role' ] ;
253
307
let addresses = server [ 'addresses' ] ;
254
308
if ( role === 'ROUTE' ) {
@@ -266,47 +320,42 @@ class RoutingDriver extends Driver {
266
320
//these are no longer valid according to server
267
321
let self = this ;
268
322
seen . forEach ( ( key ) => {
269
- self . _pool . purge ( key ) ;
323
+ console . log ( "remove seen" ) ;
324
+ self . _pools . purge ( key ) ;
270
325
} ) ;
271
326
success = true ;
272
- return ;
327
+ return new Promise ( ( resolve , reject ) => resolve ( true ) ) ;
273
328
} catch ( error ) {
274
329
//continue
275
- this . _forget ( url ) ;
276
330
console . log ( error ) ;
331
+ this . _forget ( url ) ;
277
332
}
278
333
}
279
334
335
+ let errorMsg = "Server could not perform discovery, please open a new driver with a different seed address." ;
280
336
if ( this . onError ) {
281
- this . onError ( "Server could not perform discovery, please open a new driver with a different seed address." ) ;
337
+ this . onError ( errorMsg ) ;
282
338
}
283
- this . close ( ) ;
284
- }
285
339
286
- //TODO make nice, expose constants?
287
- session ( mode ) {
288
- let conn = this . _aquireConnection ( mode ) ;
289
- return this . _createSession ( conn ) ;
340
+ return new Promise ( ( resolve , reject ) => reject ( errorMsg ) ) ;
290
341
}
291
342
292
- _aquireConnection ( mode ) {
343
+ _acquireConnection ( mode ) {
293
344
//make sure we have enough servers
294
- this . _checkServers ( ) ;
295
-
296
345
let m = mode || WRITE ;
297
346
if ( m === READ ) {
298
- return this . _pools . acquire ( this . _readers . hop ( ) ) ;
347
+ return this . _pool . acquire ( this . _readers . hop ( ) ) ;
299
348
} else if ( m === WRITE ) {
300
- return this . _pools . acquire ( this . _writers . hop ( ) ) ;
349
+ return this . _pool . acquire ( this . _writers . hop ( ) ) ;
301
350
} else {
302
351
//TODO fail
303
352
}
304
353
}
305
354
306
355
_allServers ( ) {
307
356
let seen = new Set ( this . _routers . toArray ( ) ) ;
308
- let writers = this . _writers . toArray ( )
309
- let readers = this . _readers . toArray ( )
357
+ let writers = this . _writers . toArray ( ) ;
358
+ let readers = this . _readers . toArray ( ) ;
310
359
for ( let i = 0 ; i < writers . length ; i ++ ) {
311
360
seen . add ( writers [ i ] ) ;
312
361
}
@@ -319,18 +368,19 @@ class RoutingDriver extends Driver {
319
368
async _call ( url ) {
320
369
let conn = this . _pool . acquire ( url ) ;
321
370
let session = this . _createSession ( conn ) ;
322
- console . log ( "calling " + GET_SERVERS ) ;
323
371
return session . run ( GET_SERVERS )
324
372
. then ( ( res ) => {
325
373
session . close ( ) ;
326
374
return res ;
327
375
} ) . catch ( ( err ) => {
376
+ console . log ( err ) ;
328
377
this . _forget ( url ) ;
329
378
return Promise . reject ( err ) ;
330
379
} ) ;
331
380
}
332
381
333
382
_forget ( url ) {
383
+ console . log ( "forget" ) ;
334
384
this . _pools . purge ( url ) ;
335
385
this . _routers . remove ( url ) ;
336
386
this . _readers . remove ( url ) ;
@@ -426,9 +476,12 @@ let USER_AGENT = "neo4j-javascript/" + VERSION;
426
476
function driver ( url , authToken , config = { } ) {
427
477
let sch = scheme ( url ) ;
428
478
if ( sch === "bolt+routing://" ) {
429
- return new RoutingDriver ( url , USER_AGENT , authToken , config ) ;
430
- } else {
479
+ return new RoutingDriver ( url , USER_AGENT , authToken , config ) ;
480
+ } else if ( sch === "bolt://" ) {
431
481
return new Driver ( url , USER_AGENT , authToken , config ) ;
482
+ } else {
483
+ throw new Error ( "Unknown scheme: " + sch ) ;
484
+
432
485
}
433
486
}
434
487
0 commit comments