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 38243b868..5b7de7ee5 100644 --- a/packages/bolt-connection/src/connection-provider/connection-provider-routing.js +++ b/packages/bolt-connection/src/connection-provider/connection-provider-routing.js @@ -89,6 +89,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider this._loadBalancingStrategy = new LeastConnectedLoadBalancingStrategy( this._connectionPool ) + this._startTime = 0 this._hostNameResolver = hostNameResolver this._dnsResolver = new HostNameResolver() this._log = log @@ -152,6 +153,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider (error, address, conn) => this._handleSecurityError(error, address, conn, context.database) ) + this._startTime = new Date().getTime() let conn if (this.SSREnabled() && homeDb !== undefined && database === '') { const currentRoutingTable = this._routingTableRegistry.get( @@ -205,7 +207,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider } try { - const connection = await this._connectionPool.acquire({ auth }, address) + const connection = await this._connectionPool.acquire({ auth, startTime: this._startTime }, address) if (auth) { await this._verifyStickyConnection({ @@ -585,7 +587,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider async _createSessionForRediscovery (routerAddress, bookmarks, impersonatedUser, auth) { try { - const connection = await this._connectionPool.acquire({ auth }, routerAddress) + const connection = await this._connectionPool.acquire({ auth, startTime: this._startTime }, routerAddress) if (auth) { await this._verifyStickyConnection({ 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 297e87d78..c22f3462a 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 @@ -3494,7 +3494,7 @@ describe.each([ .catch(functional.identity) expect(error).toEqual(newError('Driver is connected to a database that does not support user switch.')) - expect(poolAcquire).toHaveBeenCalledWith({ auth }, server3) + expect(poolAcquire).toHaveBeenCalledWith({ auth, startTime: expect.any(Number) }, server3) expect(connection.release).toHaveBeenCalled() expect(connection._sticky).toEqual(isStickyConn) }) @@ -3536,7 +3536,7 @@ describe.each([ .catch(functional.identity) expect(error).toEqual(newError('Driver is connected to a database that does not support user switch.')) - expect(poolAcquire).toHaveBeenCalledWith({ auth }, server1) + expect(poolAcquire).toHaveBeenCalledWith({ auth, startTime: expect.any(Number) }, server1) expect(connection.release).toHaveBeenCalled() expect(connection._sticky).toEqual(isStickyConn) }) @@ -3580,7 +3580,7 @@ describe.each([ .catch(functional.identity) expect(error).toEqual(newError('Driver is connected to a database that does not support user switch.')) - expect(poolAcquire).toHaveBeenCalledWith({ auth }, server0) + expect(poolAcquire).toHaveBeenCalledWith({ auth, startTime: expect.any(Number) }, server0) expect(connection.release).toHaveBeenCalled() expect(connection._sticky).toEqual(isStickyConn) }) @@ -3609,7 +3609,7 @@ describe.each([ .catch(functional.identity) expect(error).toEqual(newError('Driver is connected to a database that does not support user switch.')) - expect(poolAcquire).toHaveBeenCalledWith({ auth }, server0) + expect(poolAcquire).toHaveBeenCalledWith({ auth, startTime: expect.any(Number) }, server0) expect(connection.release).toHaveBeenCalled() expect(connection._sticky).toEqual(isStickyConn) }) diff --git a/packages/core/src/internal/pool/pool.ts b/packages/core/src/internal/pool/pool.ts index 06920c176..43ec04dde 100644 --- a/packages/core/src/internal/pool/pool.ts +++ b/packages/core/src/internal/pool/pool.ts @@ -28,6 +28,7 @@ type ValidateOnRelease = (resource: R) => (Promise< type InstallObserver = (resource: R, observer: unknown) => void type RemoveObserver = (resource: R) => void interface AcquisitionConfig { requireNew?: boolean } +interface AcquisitionContext { startTime?: number, forceReAuth?: boolean, skipReAuth?: boolean, auth?: object, triggerValidation?: boolean } interface ConstructorParam { create?: Create @@ -111,12 +112,13 @@ class Pool { * @param {boolean} config.requireNew Indicate it requires a new resource * @return {Promise} resource that is ready to use. */ - async acquire (acquisitionContext: unknown, address: ServerAddress, config?: AcquisitionConfig): Promise { + async acquire (acquisitionContext: AcquisitionContext, address: ServerAddress, config?: AcquisitionConfig): Promise { const key = address.asKey() // We're out of resources and will try to acquire later on when an existing resource is released. const allRequests = this._acquireRequests const requests = allRequests[key] + const elapsedTime = (acquisitionContext.startTime != null && acquisitionContext.startTime !== 0) ? new Date().getTime() - acquisitionContext.startTime : 0 if (requests == null) { allRequests[key] = [] } @@ -143,7 +145,7 @@ class Pool { ) ) } - }, this._acquisitionTimeout) + }, this._acquisitionTimeout - elapsedTime) if (typeof timeoutId === 'object') { // eslint-disable-next-line diff --git a/packages/neo4j-driver-deno/lib/bolt-connection/connection-provider/connection-provider-routing.js b/packages/neo4j-driver-deno/lib/bolt-connection/connection-provider/connection-provider-routing.js index 46014726f..29018f608 100644 --- a/packages/neo4j-driver-deno/lib/bolt-connection/connection-provider/connection-provider-routing.js +++ b/packages/neo4j-driver-deno/lib/bolt-connection/connection-provider/connection-provider-routing.js @@ -89,6 +89,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider this._loadBalancingStrategy = new LeastConnectedLoadBalancingStrategy( this._connectionPool ) + this._startTime = 0 this._hostNameResolver = hostNameResolver this._dnsResolver = new HostNameResolver() this._log = log @@ -152,6 +153,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider (error, address, conn) => this._handleSecurityError(error, address, conn, context.database) ) + this._startTime = new Date().getTime() let conn if (this.SSREnabled() && homeDb !== undefined && database === '') { const currentRoutingTable = this._routingTableRegistry.get( @@ -205,7 +207,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider } try { - const connection = await this._connectionPool.acquire({ auth }, address) + const connection = await this._connectionPool.acquire({ auth, startTime: this._startTime }, address) if (auth) { await this._verifyStickyConnection({ @@ -585,7 +587,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider async _createSessionForRediscovery (routerAddress, bookmarks, impersonatedUser, auth) { try { - const connection = await this._connectionPool.acquire({ auth }, routerAddress) + const connection = await this._connectionPool.acquire({ auth, startTime: this._startTime }, routerAddress) if (auth) { await this._verifyStickyConnection({ diff --git a/packages/neo4j-driver-deno/lib/core/internal/pool/pool.ts b/packages/neo4j-driver-deno/lib/core/internal/pool/pool.ts index ecf4f1085..7408c6dcd 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/pool/pool.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/pool/pool.ts @@ -28,6 +28,7 @@ type ValidateOnRelease = (resource: R) => (Promise< type InstallObserver = (resource: R, observer: unknown) => void type RemoveObserver = (resource: R) => void interface AcquisitionConfig { requireNew?: boolean } +interface AcquisitionContext { startTime?: number, forceReAuth?: boolean, skipReAuth?: boolean, auth?: object, triggerValidation?: boolean } interface ConstructorParam { create?: Create @@ -111,12 +112,13 @@ class Pool { * @param {boolean} config.requireNew Indicate it requires a new resource * @return {Promise} resource that is ready to use. */ - async acquire (acquisitionContext: unknown, address: ServerAddress, config?: AcquisitionConfig): Promise { + async acquire (acquisitionContext: AcquisitionContext, address: ServerAddress, config?: AcquisitionConfig): Promise { const key = address.asKey() // We're out of resources and will try to acquire later on when an existing resource is released. const allRequests = this._acquireRequests const requests = allRequests[key] + const elapsedTime = (acquisitionContext.startTime != null && acquisitionContext.startTime !== 0) ? new Date().getTime() - acquisitionContext.startTime : 0 if (requests == null) { allRequests[key] = [] } @@ -143,7 +145,7 @@ class Pool { ) ) } - }, this._acquisitionTimeout) + }, this._acquisitionTimeout - elapsedTime) if (typeof timeoutId === 'object') { // eslint-disable-next-line diff --git a/packages/testkit-backend/src/skipped-tests/common.js b/packages/testkit-backend/src/skipped-tests/common.js index 1b23dfe04..6c62a27e7 100644 --- a/packages/testkit-backend/src/skipped-tests/common.js +++ b/packages/testkit-backend/src/skipped-tests/common.js @@ -198,10 +198,6 @@ const skippedTests = [ skip( 'Needs trying all DNS resolved addresses for hosts in the routing table', ifEndsWith('.test_ipv6_read').and(startsWith('stub.routing.test_routing_')) - ), - skip( - 'Driver has separate timeouts for every connection it attempts to open. This will change in 6.0', - ifEquals('stub.homedb.test_homedb.TestHomeDbMixedCluster.test_connection_acquisition_timeout_during_fallback') ) ] diff --git a/testkit/testkit.json b/testkit/testkit.json index 0b9944108..d670dadc0 100644 --- a/testkit/testkit.json +++ b/testkit/testkit.json @@ -1,6 +1,6 @@ { "testkit": { "uri": "https://github.com/neo4j-drivers/testkit.git", - "ref": "6.x" + "ref": "connection-acquisition-6x-change" } }