From bbeddd252bb3a59a295c17bcc20f259deaa03d09 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Mon, 2 May 2022 14:47:43 +0200 Subject: [PATCH] Keep seed router address in the pool after routing table Forgetting the seed router was causing the connection to the seed router being recreated whenever the routing table is fetched and the seed router is not part of the cluster formation. For cases where the database name is set in the session, the driver will have to fetch the routing table for the default/home database for discovering the database name and make it consitent during the session lifetime. In this scenario, the seed router will be always used during the discovery. So, a new connection to the seed router will be created for each session. The solution for this issue is to keep the seed router in the pool during the update routing table process. This way, the same connections for the seed router can be re-used. --- .../connection-provider-routing.js | 2 +- .../connection-provider-routing.test.js | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/bolt-connection/src/connection-provider/connection-provider-routing.js b/packages/bolt-connection/src/connection-provider/connection-provider-routing.js index 0dbe88b26..87f4549c1 100644 --- a/packages/bolt-connection/src/connection-provider/connection-provider-routing.js +++ b/packages/bolt-connection/src/connection-provider/connection-provider-routing.js @@ -535,7 +535,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider async _updateRoutingTable (newRoutingTable, onDatabaseNameResolved) { // close old connections to servers not present in the new routing table - await this._connectionPool.keepAll(newRoutingTable.allServers()) + await this._connectionPool.keepAll([...newRoutingTable.allServers(), this._seedRouter]) this._routingTableRegistry.removeExpired() this._routingTableRegistry.register( newRoutingTable diff --git a/packages/bolt-connection/test/connection-provider/connection-provider-routing.test.js b/packages/bolt-connection/test/connection-provider/connection-provider-routing.test.js index 509f5c8e8..ad67dfabb 100644 --- a/packages/bolt-connection/test/connection-provider/connection-provider-routing.test.js +++ b/packages/bolt-connection/test/connection-provider/connection-provider-routing.test.js @@ -463,6 +463,47 @@ describe('#unit RoutingConnectionProvider', () => { }) }, 10000) + it.each(usersDataSet)('keeps the seed router in the pool after [user=%s]', (user, done) => { + const pool = newPool() + const updatedRoutingTable = newRoutingTable( + null, + [serverA, serverB], + [serverC, serverD], + [serverE, serverF] + ) + + const connectionProvider = newRoutingConnectionProviderWithSeedRouter( + server0, + [server0], // seed router address resolves just to itself + [ + newRoutingTable( + null, + [server1, server2, server3], + [server4, server5], + [server6, server7], + int(0) // expired routing table + ) + ], + { + null: { + 'server1:7687': null, // returns no routing table + 'server2:7687': null, // returns no routing table + 'server3:7687': null, // returns no routing table + 'server0:7687': updatedRoutingTable + } + }, + pool + ) + + connectionProvider + .acquireConnection({ accessMode: READ, database: null, impersonatedUser: user }) + .then(connection => { + expect(connection.address).toEqual(serverC) + expect(pool.has(server0)).toBeTruthy() + + }).finally(done) + }, 10000) + it.each(usersDataSet)('refreshes routing table without readers to get read connection [user=%s]', (user, done) => { const pool = newPool() const updatedRoutingTable = newRoutingTable(