Skip to content

Commit 8bf582c

Browse files
committed
Forget last router when rediscovery fails
Last router in the routing table was not forgotten correctly when none of the routers respond. This commit makes code correctly foget it.
1 parent 7dbe303 commit 8bf582c

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

src/v1/internal/connection-providers.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,8 @@ export class LoadBalancer extends ConnectionProvider {
104104
} else {
105105
// returned routing table was undefined, this means a connection error happened and we need to forget the
106106
// previous router and try the next one
107-
const previousRouter = knownRouters[currentIndex - 1];
108-
if (previousRouter) {
109-
currentRoutingTable.forgetRouter(previousRouter);
110-
}
107+
const previousRouterIndex = currentIndex - 1;
108+
this._forgetRouter(currentRoutingTable, knownRouters, previousRouterIndex);
111109
}
112110

113111
// try next router
@@ -116,12 +114,17 @@ export class LoadBalancer extends ConnectionProvider {
116114
});
117115
}, Promise.resolve(null));
118116

119-
// todo: who removes the final router when all routers fail?
120117
return refreshedTablePromise.then(newRoutingTable => {
121118
if (newRoutingTable && !newRoutingTable.writers.isEmpty()) {
122119
this._updateRoutingTable(newRoutingTable);
123120
return newRoutingTable;
124121
}
122+
123+
// forget the last known router because it did not return a valid routing table
124+
const lastRouterIndex = knownRouters.length - 1;
125+
this._forgetRouter(currentRoutingTable, knownRouters, lastRouterIndex);
126+
127+
// none of the existing routers returned valid routing table, throw exception
125128
throw newError('Could not perform discovery. No routing servers available.', SERVICE_UNAVAILABLE);
126129
});
127130
}
@@ -142,4 +145,11 @@ export class LoadBalancer extends ConnectionProvider {
142145
// make this driver instance aware of the new table
143146
this._routingTable = newRoutingTable;
144147
}
148+
149+
_forgetRouter(routingTable, routersArray, routerIndex) {
150+
const address = routersArray[routerIndex];
151+
if (address) {
152+
routingTable.forgetRouter(address);
153+
}
154+
}
145155
}

test/internal/connection-providers.test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,46 @@ describe('LoadBalancer', () => {
539539
});
540540
});
541541

542+
it('forgets all routers when they fail while acquiring read connection', done => {
543+
const loadBalancer = newLoadBalancer(
544+
['server-1', 'server-2', 'server-3'],
545+
['server-4', 'server-5'],
546+
['server-6', 'server-7'],
547+
newPool(),
548+
int(0) // expired routing table
549+
);
550+
551+
loadBalancer.acquireConnection(READ).catch(error => {
552+
expect(error.code).toEqual(SERVICE_UNAVAILABLE);
553+
expectRoutingTable(loadBalancer,
554+
[],
555+
['server-4', 'server-5'],
556+
['server-6', 'server-7']
557+
);
558+
done();
559+
});
560+
});
561+
562+
it('forgets all routers when they fail while acquiring write connection', done => {
563+
const loadBalancer = newLoadBalancer(
564+
['server-1', 'server-2', 'server-3'],
565+
['server-4', 'server-5'],
566+
['server-6', 'server-7'],
567+
newPool(),
568+
int(0) // expired routing table
569+
);
570+
571+
loadBalancer.acquireConnection(WRITE).catch(error => {
572+
expect(error.code).toEqual(SERVICE_UNAVAILABLE);
573+
expectRoutingTable(loadBalancer,
574+
[],
575+
['server-4', 'server-5'],
576+
['server-6', 'server-7']
577+
);
578+
done();
579+
});
580+
});
581+
542582
});
543583

544584
function newLoadBalancer(routers, readers, writers, pool = null, expirationTime = Integer.MAX_VALUE, routerToRoutingTable = {}) {

0 commit comments

Comments
 (0)