@@ -116,7 +116,7 @@ class Driver {
116116 }
117117
118118 _createSession ( conn ) {
119- return new Session ( conn , ( cb ) => {
119+ return new Session ( new Promise ( ( resolve , reject ) => resolve ( conn ) ) , ( cb ) => {
120120 // This gets called on Session#close(), and is where we return
121121 // the pooled 'connection' instance.
122122
@@ -204,6 +204,47 @@ class RoundRobinArray {
204204}
205205
206206let 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+
207248class RoutingDriver extends Driver {
208249
209250 constructor ( url , userAgent = 'neo4j-javascript/0.0' , token = { } , config = { } ) {
@@ -213,15 +254,25 @@ class RoutingDriver extends Driver {
213254 this . _readers = new RoundRobinArray ( ) ;
214255 this . _writers = new RoundRobinArray ( ) ;
215256 this . _expires = Date . now ( ) ;
216- this . _checkServers ( ) ;
217257 }
218258
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 ( ) {
220269 if ( this . _expires < Date . now ( ) ||
221270 this . _routers . empty ( ) ||
222271 this . _readers . empty ( ) ||
223272 this . _writers . empty ( ) ) {
224- this . _callServers ( ) ;
273+ return await this . _callServers ( ) ;
274+ } else {
275+ return new Promise ( ( resolve , reject ) => resolve ( false ) ) ;
225276 }
226277 }
227278
@@ -239,16 +290,19 @@ class RoutingDriver extends Driver {
239290 let url = this . _routers . hop ( ) ;
240291 try {
241292 let res = await this . _call ( url ) ;
293+ console . log ( "got result" ) ;
242294 if ( res . records . length != 1 ) continue ;
243295 let record = res . records [ 0 ] ;
244296 //Note we are loosing precision here but we are not
245297 //terribly worried since it is only
246298 //for dates more than 140000 years into the future.
247299 this . _expires += record . get ( 'ttl' ) . toNumber ( ) ;
248300 let servers = record . get ( 'servers' ) ;
301+ console . log ( servers ) ;
249302 for ( let i = 0 ; i <= servers . length ; i ++ ) {
250303 let server = servers [ i ] ;
251- seen . delete ( server ) ;
304+ seen . remove ( server ) ;
305+
252306 let role = server [ 'role' ] ;
253307 let addresses = server [ 'addresses' ] ;
254308 if ( role === 'ROUTE' ) {
@@ -266,47 +320,42 @@ class RoutingDriver extends Driver {
266320 //these are no longer valid according to server
267321 let self = this ;
268322 seen . forEach ( ( key ) => {
269- self . _pool . purge ( key ) ;
323+ console . log ( "remove seen" ) ;
324+ self . _pools . purge ( key ) ;
270325 } ) ;
271326 success = true ;
272- return ;
327+ return new Promise ( ( resolve , reject ) => resolve ( true ) ) ;
273328 } catch ( error ) {
274329 //continue
275- this . _forget ( url ) ;
276330 console . log ( error ) ;
331+ this . _forget ( url ) ;
277332 }
278333 }
279334
335+ let errorMsg = "Server could not perform discovery, please open a new driver with a different seed address." ;
280336 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 ) ;
282338 }
283- this . close ( ) ;
284- }
285339
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 ) ) ;
290341 }
291342
292- _aquireConnection ( mode ) {
343+ _acquireConnection ( mode ) {
293344 //make sure we have enough servers
294- this . _checkServers ( ) ;
295-
296345 let m = mode || WRITE ;
297346 if ( m === READ ) {
298- return this . _pools . acquire ( this . _readers . hop ( ) ) ;
347+ return this . _pool . acquire ( this . _readers . hop ( ) ) ;
299348 } else if ( m === WRITE ) {
300- return this . _pools . acquire ( this . _writers . hop ( ) ) ;
349+ return this . _pool . acquire ( this . _writers . hop ( ) ) ;
301350 } else {
302351 //TODO fail
303352 }
304353 }
305354
306355 _allServers ( ) {
307356 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 ( ) ;
310359 for ( let i = 0 ; i < writers . length ; i ++ ) {
311360 seen . add ( writers [ i ] ) ;
312361 }
@@ -319,18 +368,19 @@ class RoutingDriver extends Driver {
319368 async _call ( url ) {
320369 let conn = this . _pool . acquire ( url ) ;
321370 let session = this . _createSession ( conn ) ;
322- console . log ( "calling " + GET_SERVERS ) ;
323371 return session . run ( GET_SERVERS )
324372 . then ( ( res ) => {
325373 session . close ( ) ;
326374 return res ;
327375 } ) . catch ( ( err ) => {
376+ console . log ( err ) ;
328377 this . _forget ( url ) ;
329378 return Promise . reject ( err ) ;
330379 } ) ;
331380 }
332381
333382 _forget ( url ) {
383+ console . log ( "forget" ) ;
334384 this . _pools . purge ( url ) ;
335385 this . _routers . remove ( url ) ;
336386 this . _readers . remove ( url ) ;
@@ -426,9 +476,12 @@ let USER_AGENT = "neo4j-javascript/" + VERSION;
426476function driver ( url , authToken , config = { } ) {
427477 let sch = scheme ( url ) ;
428478 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://" ) {
431481 return new Driver ( url , USER_AGENT , authToken , config ) ;
482+ } else {
483+ throw new Error ( "Unknown scheme: " + sch ) ;
484+
432485 }
433486}
434487
0 commit comments