diff --git a/src/v1/driver.js b/src/v1/driver.js index ec6394a26..1d7c3ea0a 100644 --- a/src/v1/driver.js +++ b/src/v1/driver.js @@ -25,7 +25,9 @@ import {newError, SERVICE_UNAVAILABLE} from './error'; import {DirectConnectionProvider} from './internal/connection-providers'; import Bookmark from './internal/bookmark'; import ConnectivityVerifier from './internal/connectivity-verifier'; -import PoolConfig from './internal/pool-config'; +import PoolConfig, {DEFAULT_ACQUISITION_TIMEOUT, DEFAULT_MAX_SIZE} from './internal/pool-config'; + +const DEFAULT_MAX_CONNECTION_LIFETIME = 60 * 60 * 1000; // 1 hour const READ = 'READ', WRITE = 'WRITE'; /** @@ -115,14 +117,8 @@ class Driver { } const maxConnectionLifetime = this._config.maxConnectionLifetime; - if (maxConnectionLifetime) { - const lifetime = Date.now() - conn.creationTimestamp; - if (lifetime > maxConnectionLifetime) { - return false; - } - } - - return true; + const lifetime = Date.now() - conn.creationTimestamp; + return lifetime <= maxConnectionLifetime; } /** @@ -238,19 +234,20 @@ class _ConnectionStreamObserver extends StreamObserver { * @private */ function sanitizeConfig(config) { - config.maxConnectionLifetime = sanitizeIntValue(config.maxConnectionLifetime); - config.maxConnectionPoolSize = sanitizeIntValue(config.maxConnectionPoolSize); - config.connectionAcquisitionTimeout = sanitizeIntValue(config.connectionAcquisitionTimeout); + config.maxConnectionLifetime = sanitizeIntValue(config.maxConnectionLifetime, DEFAULT_MAX_CONNECTION_LIFETIME); + config.maxConnectionPoolSize = sanitizeIntValue(config.maxConnectionPoolSize, DEFAULT_MAX_SIZE); + config.connectionAcquisitionTimeout = sanitizeIntValue(config.connectionAcquisitionTimeout, DEFAULT_ACQUISITION_TIMEOUT); } -function sanitizeIntValue(value) { - if (value) { - const sanitizedValue = parseInt(value, 10); - if (sanitizedValue && sanitizedValue > 0) { - return sanitizedValue; - } +function sanitizeIntValue(rawValue, defaultWhenAbsent) { + const sanitizedValue = parseInt(rawValue, 10); + if (sanitizedValue > 0 || sanitizedValue === 0) { + return sanitizedValue; + } else if (sanitizedValue < 0) { + return Number.MAX_SAFE_INTEGER; + } else { + return defaultWhenAbsent; } - return null; } export {Driver, READ, WRITE} diff --git a/src/v1/index.js b/src/v1/index.js index 4265fdb76..5a5941709 100644 --- a/src/v1/index.js +++ b/src/v1/index.js @@ -111,7 +111,7 @@ const USER_AGENT = "neo4j-javascript/" + VERSION; * // The max number of connections that are allowed idle in the pool at any time. * // Connection will be destroyed if this threshold is exceeded. * // Deprecated: please use maxConnectionPoolSize instead. - * connectionPoolSize: 50, + * connectionPoolSize: 100, * * // The maximum total number of connections allowed to be managed by the connection pool, per host. * // This includes both in-use and idle connections. No maximum connection pool size is imposed @@ -125,7 +125,7 @@ const USER_AGENT = "neo4j-javascript/" + VERSION; * // to a slightly smaller value than the one configured in network equipment (load balancer, proxy, firewall, * // etc. can also limit maximum connection lifetime). No maximum lifetime limit is imposed by default. Zero * // and negative values result in lifetime not being checked. - * maxConnectionLifetime: 30 * 60 * 1000, // 30 minutes + * maxConnectionLifetime: 60 * 60 * 1000, // 1 hour * * // The maximum amount of time to wait to acquire a connection from the pool (to either create a new * // connection or borrow an existing one. diff --git a/src/v1/internal/pool-config.js b/src/v1/internal/pool-config.js index a5286b285..cd751810b 100644 --- a/src/v1/internal/pool-config.js +++ b/src/v1/internal/pool-config.js @@ -17,8 +17,8 @@ * limitations under the License. */ -const DEFAULT_MAX_SIZE = 50; -const DEFAULT_ACQUISITION_TIMEOUT = 60000; +const DEFAULT_MAX_SIZE = 100; +const DEFAULT_ACQUISITION_TIMEOUT = 60 * 1000; // 60 seconds export default class PoolConfig { diff --git a/test/v1/driver.test.js b/test/v1/driver.test.js index 748bccc7b..48b222a6f 100644 --- a/test/v1/driver.test.js +++ b/test/v1/driver.test.js @@ -21,6 +21,7 @@ import neo4j from '../../src/v1'; import sharedNeo4j from '../internal/shared-neo4j'; import FakeConnection from '../internal/fake-connection'; import lolex from 'lolex'; +import {DEFAULT_ACQUISITION_TIMEOUT, DEFAULT_MAX_SIZE} from '../../src/v1/internal/pool-config'; describe('driver', () => { @@ -191,13 +192,10 @@ describe('driver', () => { expect(() => neo4j.driver('bolt://localhost:7687/?policy=my_policy')).toThrow(); }); - it('should sanitize maxConnectionLifetime in the config', () => { - validateMaxConnectionLifetime({}, null); - validateMaxConnectionLifetime({maxConnectionLifetime: 42}, 42); - validateMaxConnectionLifetime({maxConnectionLifetime: 0}, null); - validateMaxConnectionLifetime({maxConnectionLifetime: '42'}, 42); - validateMaxConnectionLifetime({maxConnectionLifetime: '042'}, 42); - validateMaxConnectionLifetime({maxConnectionLifetime: -42}, null); + it('should sanitize pool setting values in the config', () => { + testConfigSanitizing('maxConnectionLifetime', 60 * 60 * 1000); + testConfigSanitizing('maxConnectionPoolSize', DEFAULT_MAX_SIZE); + testConfigSanitizing('connectionAcquisitionTimeout', DEFAULT_ACQUISITION_TIMEOUT); }); it('should treat closed connections as invalid', () => { @@ -321,10 +319,19 @@ describe('driver', () => { return neo4j.auth.basic('neo4j', 'who would use such a password'); } - function validateMaxConnectionLifetime(config, expectedValue) { + function testConfigSanitizing(configProperty, defaultValue) { + validateConfigSanitizing({}, defaultValue); + validateConfigSanitizing({[configProperty]: 42}, 42); + validateConfigSanitizing({[configProperty]: 0}, 0); + validateConfigSanitizing({[configProperty]: '42'}, 42); + validateConfigSanitizing({[configProperty]: '042'}, 42); + validateConfigSanitizing({[configProperty]: -42}, Number.MAX_SAFE_INTEGER); + } + + function validateConfigSanitizing(config, configProperty, expectedValue) { const driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, config); try { - expect(driver._config.maxConnectionLifetime).toEqual(expectedValue); + expect(driver._config[configProperty]).toEqual(expectedValue); } finally { driver.close(); } diff --git a/test/v1/examples.test.js b/test/v1/examples.test.js index a9a4afd55..7f4fbdfc1 100644 --- a/test/v1/examples.test.js +++ b/test/v1/examples.test.js @@ -107,6 +107,38 @@ describe('examples', () => { }; }); + it('config connection pool example', done => { + // tag::config-connection-pool[] + const driver = neo4j.driver(uri, neo4j.auth.basic(user, password), + { + maxConnectionLifetime: 30*60*60, + maxConnectionPoolSize: 50, + connectionAcquisitionTimeout: 2*60 + } + ); + // end::config-connection-pool[] + + driver.onCompleted = () => { + driver.close(); + done(); + }; + }); + + it('config load balancing example', done => { + // tag::config-load-balancing-strategy[] + const driver = neo4j.driver(uri, neo4j.auth.basic(user, password), + { + loadBalancingStrategy: "least_connected" + } + ); + // end::config-load-balancing-strategy[] + + driver.onCompleted = () => { + driver.close(); + done(); + }; + }); + it('config max retry time example', done => { // tag::config-max-retry-time[] const maxRetryTimeMs = 15 * 1000; // 15 seconds