2020import { newError , SERVICE_UNAVAILABLE , SESSION_EXPIRED } from '../error' ;
2121import { READ , WRITE } from '../driver' ;
2222import Session from '../session' ;
23- import RoundRobinArray from './round-robin-array' ;
2423import RoutingTable from './routing-table' ;
2524import Rediscovery from './rediscovery' ;
2625import hasFeature from './features' ;
2726import { DnsHostNameResolver , DummyHostNameResolver } from './host-name-resolvers' ;
2827import RoutingUtil from './routing-util' ;
28+ import RoundRobinLoadBalancingStrategy from './round-robin-load-balancing-strategy' ;
2929
3030class ConnectionProvider {
3131
@@ -65,20 +65,23 @@ export class LoadBalancer extends ConnectionProvider {
6565 constructor ( address , routingContext , connectionPool , driverOnErrorCallback ) {
6666 super ( ) ;
6767 this . _seedRouter = address ;
68- this . _routingTable = new RoutingTable ( new RoundRobinArray ( [ this . _seedRouter ] ) ) ;
68+ this . _routingTable = new RoutingTable ( [ this . _seedRouter ] ) ;
6969 this . _rediscovery = new Rediscovery ( new RoutingUtil ( routingContext ) ) ;
7070 this . _connectionPool = connectionPool ;
7171 this . _driverOnErrorCallback = driverOnErrorCallback ;
7272 this . _hostNameResolver = LoadBalancer . _createHostNameResolver ( ) ;
73+ this . _loadBalancingStrategy = new RoundRobinLoadBalancingStrategy ( ) ;
7374 this . _useSeedRouter = false ;
7475 }
7576
7677 acquireConnection ( accessMode ) {
7778 const connectionPromise = this . _freshRoutingTable ( accessMode ) . then ( routingTable => {
7879 if ( accessMode === READ ) {
79- return this . _acquireConnectionToServer ( routingTable . readers , 'read' ) ;
80+ const address = this . _loadBalancingStrategy . selectReader ( routingTable . readers ) ;
81+ return this . _acquireConnectionToServer ( address , 'read' ) ;
8082 } else if ( accessMode === WRITE ) {
81- return this . _acquireConnectionToServer ( routingTable . writers , 'write' ) ;
83+ const address = this . _loadBalancingStrategy . selectWriter ( routingTable . writers ) ;
84+ return this . _acquireConnectionToServer ( address , 'write' ) ;
8285 } else {
8386 throw newError ( 'Illegal mode ' + accessMode ) ;
8487 }
@@ -95,8 +98,7 @@ export class LoadBalancer extends ConnectionProvider {
9598 this . _routingTable . forgetWriter ( address ) ;
9699 }
97100
98- _acquireConnectionToServer ( serversRoundRobinArray , serverName ) {
99- const address = serversRoundRobinArray . next ( ) ;
101+ _acquireConnectionToServer ( address , serverName ) {
100102 if ( ! address ) {
101103 return Promise . reject ( newError (
102104 `Failed to obtain connection towards ${ serverName } server. Known routing table is: ${ this . _routingTable } ` ,
@@ -115,7 +117,7 @@ export class LoadBalancer extends ConnectionProvider {
115117 }
116118
117119 _refreshRoutingTable ( currentRoutingTable ) {
118- const knownRouters = currentRoutingTable . routers . toArray ( ) ;
120+ const knownRouters = currentRoutingTable . routers ;
119121
120122 if ( this . _useSeedRouter ) {
121123 return this . _fetchRoutingTableFromSeedRouterFallbackToKnownRouters ( knownRouters , currentRoutingTable ) ;
@@ -215,7 +217,7 @@ export class LoadBalancer extends ConnectionProvider {
215217 SERVICE_UNAVAILABLE ) ;
216218 }
217219
218- if ( newRoutingTable . writers . isEmpty ( ) ) {
220+ if ( newRoutingTable . writers . length === 0 ) {
219221 // use seed router next time. this is important when cluster is partitioned. it tries to make sure driver
220222 // does not always get routing table without writers because it talks exclusively to a minority partition
221223 this . _useSeedRouter = true ;
0 commit comments