@@ -49,6 +49,12 @@ var _rediscovery = require('./rediscovery');
4949
5050var _rediscovery2 = _interopRequireDefault ( _rediscovery ) ;
5151
52+ var _features = require ( './features' ) ;
53+
54+ var _features2 = _interopRequireDefault ( _features ) ;
55+
56+ var _hostNameResolvers = require ( './host-name-resolvers' ) ;
57+
5258function _interopRequireDefault ( obj ) { return obj && obj . __esModule ? obj : { default : obj } ; }
5359
5460/**
@@ -78,7 +84,7 @@ var ConnectionProvider = function () {
7884 ( 0 , _createClass3 . default ) ( ConnectionProvider , [ {
7985 key : 'acquireConnection' ,
8086 value : function acquireConnection ( mode ) {
81- throw new Error ( 'Abstract method ' ) ;
87+ throw new Error ( 'Abstract function ' ) ;
8288 }
8389 } , {
8490 key : '_withAdditionalOnErrorCallback' ,
@@ -128,10 +134,12 @@ var LoadBalancer = exports.LoadBalancer = function (_ConnectionProvider2) {
128134
129135 var _this2 = ( 0 , _possibleConstructorReturn3 . default ) ( this , ( LoadBalancer . __proto__ || ( 0 , _getPrototypeOf2 . default ) ( LoadBalancer ) ) . call ( this ) ) ;
130136
131- _this2 . _routingTable = new _routingTable2 . default ( new _roundRobinArray2 . default ( [ address ] ) ) ;
137+ _this2 . _seedRouter = address ;
138+ _this2 . _routingTable = new _routingTable2 . default ( new _roundRobinArray2 . default ( [ _this2 . _seedRouter ] ) ) ;
132139 _this2 . _rediscovery = new _rediscovery2 . default ( ) ;
133140 _this2 . _connectionPool = connectionPool ;
134141 _this2 . _driverOnErrorCallback = driverOnErrorCallback ;
142+ _this2 . _hostNameResolver = LoadBalancer . _createHostNameResolver ( ) ;
135143 return _this2 ;
136144 }
137145
@@ -188,7 +196,50 @@ var LoadBalancer = exports.LoadBalancer = function (_ConnectionProvider2) {
188196
189197 var knownRouters = currentRoutingTable . routers . toArray ( ) ;
190198
191- var refreshedTablePromise = knownRouters . reduce ( function ( refreshedTablePromise , currentRouter , currentIndex ) {
199+ return this . _fetchNewRoutingTable ( knownRouters , currentRoutingTable ) . then ( function ( newRoutingTable ) {
200+ if ( LoadBalancer . _isValidRoutingTable ( newRoutingTable ) ) {
201+ // one of the known routers returned a valid routing table - use it
202+ return newRoutingTable ;
203+ }
204+
205+ if ( ! newRoutingTable ) {
206+ // returned routing table was undefined, this means a connection error happened and the last known
207+ // router did not return a valid routing table, so we need to forget it
208+ var lastRouterIndex = knownRouters . length - 1 ;
209+ LoadBalancer . _forgetRouter ( currentRoutingTable , knownRouters , lastRouterIndex ) ;
210+ }
211+
212+ // none of the known routers returned a valid routing table - try to use seed router address for rediscovery
213+ return _this4 . _fetchNewRoutingTableUsingSeedRouterAddress ( knownRouters , _this4 . _seedRouter ) ;
214+ } ) . then ( function ( newRoutingTable ) {
215+ if ( LoadBalancer . _isValidRoutingTable ( newRoutingTable ) ) {
216+ _this4 . _updateRoutingTable ( newRoutingTable ) ;
217+ return newRoutingTable ;
218+ }
219+
220+ // none of the existing routers returned valid routing table, throw exception
221+ throw ( 0 , _error . newError ) ( 'Could not perform discovery. No routing servers available.' , _error . SERVICE_UNAVAILABLE ) ;
222+ } ) ;
223+ }
224+ } , {
225+ key : '_fetchNewRoutingTableUsingSeedRouterAddress' ,
226+ value : function _fetchNewRoutingTableUsingSeedRouterAddress ( knownRouters , seedRouter ) {
227+ var _this5 = this ;
228+
229+ return this . _hostNameResolver . resolve ( seedRouter ) . then ( function ( resolvedRouterAddresses ) {
230+ // filter out all addresses that we've already tried
231+ var newAddresses = resolvedRouterAddresses . filter ( function ( address ) {
232+ return knownRouters . indexOf ( address ) < 0 ;
233+ } ) ;
234+ return _this5 . _fetchNewRoutingTable ( newAddresses , null ) ;
235+ } ) ;
236+ }
237+ } , {
238+ key : '_fetchNewRoutingTable' ,
239+ value : function _fetchNewRoutingTable ( routerAddresses , routingTable ) {
240+ var _this6 = this ;
241+
242+ return routerAddresses . reduce ( function ( refreshedTablePromise , currentRouter , currentIndex ) {
192243 return refreshedTablePromise . then ( function ( newRoutingTable ) {
193244 if ( newRoutingTable ) {
194245 if ( ! newRoutingTable . writers . isEmpty ( ) ) {
@@ -199,28 +250,14 @@ var LoadBalancer = exports.LoadBalancer = function (_ConnectionProvider2) {
199250 // returned routing table was undefined, this means a connection error happened and we need to forget the
200251 // previous router and try the next one
201252 var previousRouterIndex = currentIndex - 1 ;
202- _this4 . _forgetRouter ( currentRoutingTable , knownRouters , previousRouterIndex ) ;
253+ LoadBalancer . _forgetRouter ( routingTable , routerAddresses , previousRouterIndex ) ;
203254 }
204255
205256 // try next router
206- var session = _this4 . _createSessionForRediscovery ( currentRouter ) ;
207- return _this4 . _rediscovery . lookupRoutingTableOnRouter ( session , currentRouter ) ;
257+ var session = _this6 . _createSessionForRediscovery ( currentRouter ) ;
258+ return _this6 . _rediscovery . lookupRoutingTableOnRouter ( session , currentRouter ) ;
208259 } ) ;
209260 } , _promise2 . default . resolve ( null ) ) ;
210-
211- return refreshedTablePromise . then ( function ( newRoutingTable ) {
212- if ( newRoutingTable && ! newRoutingTable . writers . isEmpty ( ) ) {
213- _this4 . _updateRoutingTable ( newRoutingTable ) ;
214- return newRoutingTable ;
215- }
216-
217- // forget the last known router because it did not return a valid routing table
218- var lastRouterIndex = knownRouters . length - 1 ;
219- _this4 . _forgetRouter ( currentRoutingTable , knownRouters , lastRouterIndex ) ;
220-
221- // none of the existing routers returned valid routing table, throw exception
222- throw ( 0 , _error . newError ) ( 'Could not perform discovery. No routing servers available.' , _error . SERVICE_UNAVAILABLE ) ;
223- } ) ;
224261 }
225262 } , {
226263 key : '_createSessionForRediscovery' ,
@@ -233,27 +270,40 @@ var LoadBalancer = exports.LoadBalancer = function (_ConnectionProvider2) {
233270 } , {
234271 key : '_updateRoutingTable' ,
235272 value : function _updateRoutingTable ( newRoutingTable ) {
236- var _this5 = this ;
273+ var _this7 = this ;
237274
238275 var currentRoutingTable = this . _routingTable ;
239276
240277 // close old connections to servers not present in the new routing table
241278 var staleServers = currentRoutingTable . serversDiff ( newRoutingTable ) ;
242279 staleServers . forEach ( function ( server ) {
243- return _this5 . _connectionPool . purge ( server ) ;
280+ return _this7 . _connectionPool . purge ( server ) ;
244281 } ) ;
245282
246283 // make this driver instance aware of the new table
247284 this . _routingTable = newRoutingTable ;
248285 }
286+ } ] , [ {
287+ key : '_isValidRoutingTable' ,
288+ value : function _isValidRoutingTable ( routingTable ) {
289+ return routingTable && ! routingTable . writers . isEmpty ( ) ;
290+ }
249291 } , {
250292 key : '_forgetRouter' ,
251293 value : function _forgetRouter ( routingTable , routersArray , routerIndex ) {
252294 var address = routersArray [ routerIndex ] ;
253- if ( address ) {
295+ if ( routingTable && address ) {
254296 routingTable . forgetRouter ( address ) ;
255297 }
256298 }
299+ } , {
300+ key : '_createHostNameResolver' ,
301+ value : function _createHostNameResolver ( ) {
302+ if ( ( 0 , _features2 . default ) ( 'dns_lookup' ) ) {
303+ return new _hostNameResolvers . DnsHostNameResolver ( ) ;
304+ }
305+ return new _hostNameResolvers . DummyHostNameResolver ( ) ;
306+ }
257307 } ] ) ;
258308 return LoadBalancer ;
259309} ( ConnectionProvider ) ;
@@ -264,10 +314,10 @@ var SingleConnectionProvider = exports.SingleConnectionProvider = function (_Con
264314 function SingleConnectionProvider ( connectionPromise ) {
265315 ( 0 , _classCallCheck3 . default ) ( this , SingleConnectionProvider ) ;
266316
267- var _this6 = ( 0 , _possibleConstructorReturn3 . default ) ( this , ( SingleConnectionProvider . __proto__ || ( 0 , _getPrototypeOf2 . default ) ( SingleConnectionProvider ) ) . call ( this ) ) ;
317+ var _this8 = ( 0 , _possibleConstructorReturn3 . default ) ( this , ( SingleConnectionProvider . __proto__ || ( 0 , _getPrototypeOf2 . default ) ( SingleConnectionProvider ) ) . call ( this ) ) ;
268318
269- _this6 . _connectionPromise = connectionPromise ;
270- return _this6 ;
319+ _this8 . _connectionPromise = connectionPromise ;
320+ return _this8 ;
271321 }
272322
273323 ( 0 , _createClass3 . default ) ( SingleConnectionProvider , [ {
0 commit comments