Skip to content

Commit 9f9d644

Browse files
committed
option "convertToString" to always return strings instead of neo4j.int instances
1 parent 28eeba5 commit 9f9d644

File tree

10 files changed

+5111
-4124
lines changed

10 files changed

+5111
-4124
lines changed

lib/browser/neo4j-web.js

Lines changed: 2225 additions & 1886 deletions
Large diffs are not rendered by default.

lib/browser/neo4j-web.min.js

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/browser/neo4j-web.test.js

Lines changed: 2759 additions & 2170 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/v1/driver.js

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,15 @@ var Driver = function () {
9999
var config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
100100
(0, _classCallCheck3.default)(this, Driver);
101101

102+
sanitizeConfig(config);
103+
102104
this._url = url;
103105
this._userAgent = userAgent;
104106
this._openSessions = {};
105107
this._sessionIdGenerator = 0;
106108
this._token = token;
107109
this._config = config;
108-
this._pool = new _pool2.default(this._createConnection.bind(this), this._destroyConnection.bind(this), Driver._validateConnection.bind(this), config.connectionPoolSize);
110+
this._pool = new _pool2.default(this._createConnection.bind(this), this._destroyConnection.bind(this), this._validateConnection.bind(this), config.connectionPoolSize);
109111

110112
/**
111113
* Reference to the connection provider. Initialized lazily by {@link _getOrCreateConnectionProvider}.
@@ -145,14 +147,31 @@ var Driver = function () {
145147
**/
146148

147149
}, {
148-
key: '_destroyConnection',
150+
key: '_validateConnection',
151+
value: function _validateConnection(conn) {
152+
if (!conn.isOpen()) {
153+
return false;
154+
}
155+
156+
var maxConnectionLifetime = this._config.maxConnectionLifetime;
157+
if (maxConnectionLifetime) {
158+
var lifetime = Date.now() - conn.creationTimestamp;
159+
if (lifetime > maxConnectionLifetime) {
160+
return false;
161+
}
162+
}
149163

164+
return true;
165+
}
150166

151167
/**
152168
* Dispose of a live session, closing any associated resources.
153169
* @return {Session} new session.
154170
* @access private
155171
*/
172+
173+
}, {
174+
key: '_destroyConnection',
156175
value: function _destroyConnection(conn) {
157176
delete this._openSessions[conn._id];
158177
conn.close();
@@ -245,11 +264,6 @@ var Driver = function () {
245264
}
246265
}
247266
}], [{
248-
key: '_validateConnection',
249-
value: function _validateConnection(conn) {
250-
return conn.isOpen();
251-
}
252-
}, {
253267
key: '_validateSessionMode',
254268
value: function _validateSessionMode(rawMode) {
255269
var mode = rawMode || WRITE;
@@ -305,6 +319,25 @@ var _ConnectionStreamObserver = function (_StreamObserver) {
305319
return _ConnectionStreamObserver;
306320
}(_streamObserver2.default);
307321

322+
/**
323+
* @private
324+
*/
325+
326+
327+
function sanitizeConfig(config) {
328+
var maxConnectionLifetime = config.maxConnectionLifetime;
329+
if (maxConnectionLifetime) {
330+
var sanitizedMaxConnectionLifetime = parseInt(maxConnectionLifetime, 10);
331+
if (sanitizedMaxConnectionLifetime && sanitizedMaxConnectionLifetime > 0) {
332+
config.maxConnectionLifetime = sanitizedMaxConnectionLifetime;
333+
} else {
334+
config.maxConnectionLifetime = null;
335+
}
336+
} else {
337+
config.maxConnectionLifetime = null;
338+
}
339+
}
340+
308341
exports.Driver = Driver;
309342
exports.READ = READ;
310343
exports.WRITE = WRITE;

lib/v1/index.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ var USER_AGENT = "neo4j-javascript/" + _version2.default;
125125
* // TRUST_SYSTEM_CA_SIGNED_CERTIFICATES meand that you trust whatever certificates
126126
* // are in the default certificate chain of th
127127
* trust: "TRUST_ALL_CERTIFICATES" | "TRUST_ON_FIRST_USE" | "TRUST_SIGNED_CERTIFICATES" |
128-
* "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES" | "TRUST_SYSTEM_CA_SIGNED_CERTIFICATES",
128+
* "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES" | "TRUST_SYSTEM_CA_SIGNED_CERTIFICATES",
129129
*
130130
* // List of one or more paths to trusted encryption certificates. This only
131131
* // works in the NodeJS bundle, and only matters if you use "TRUST_CUSTOM_CA_SIGNED_CERTIFICATES".
@@ -144,11 +144,20 @@ var USER_AGENT = "neo4j-javascript/" + _version2.default;
144144
* // Connection will be destroyed if this threshold is exceeded.
145145
* connectionPoolSize: 50,
146146
*
147+
* // The maximum allowed lifetime for a pooled connection in milliseconds. Pooled connections older than this
148+
* // threshold will be closed and removed from the pool. Such discarding happens during connection acquisition
149+
* // so that new session is never backed by an old connection. Setting this option to a low value will cause
150+
* // a high connection churn and might result in a performance hit. It is recommended to set maximum lifetime
151+
* // to a slightly smaller value than the one configured in network equipment (load balancer, proxy, firewall,
152+
* // etc. can also limit maximum connection lifetime). No maximum lifetime limit is imposed by default. Zero
153+
* // and negative values result in lifetime not being checked.
154+
* maxConnectionLifetime: 30 * 60 * 1000, // 30 minutes
155+
*
147156
* // Specify the maximum time in milliseconds transactions are allowed to retry via
148157
* // {@link Session#readTransaction()} and {@link Session#writeTransaction()} functions. These functions
149158
* // will retry the given unit of work on `ServiceUnavailable`, `SessionExpired` and transient errors with
150159
* // exponential backoff using initial delay of 1 second. Default value is 30000 which is 30 seconds.
151-
* maxTransactionRetryTime: 30000,
160+
* maxTransactionRetryTime: 30000, // 30 seconds
152161
*
153162
* // Provide an alternative load balancing strategy for the routing driver to use.
154163
* // Driver uses "least_connected" by default.

lib/v1/internal/connector.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ var Connection = function () {
214214
* callback property
215215
* @param url - url to connect to
216216
*/
217-
function Connection(channel, url) {
217+
function Connection(channel, url, config) {
218218
(0, _classCallCheck3.default)(this, Connection);
219219

220220
/**
@@ -224,13 +224,14 @@ var Connection = function () {
224224
*/
225225
this.url = url;
226226
this.server = { address: url };
227+
this.creationTimestamp = Date.now();
227228
this._pendingObservers = [];
228229
this._currentObserver = undefined;
229230
this._ch = channel;
230231
this._dechunker = new _chunking.Dechunker();
231232
this._chunker = new _chunking.Chunker(channel);
232233
this._packer = new _packstream.Packer(this._chunker);
233-
this._unpacker = new _packstream.Unpacker();
234+
this._unpacker = new _packstream.Unpacker(config);
234235

235236
this._isHandlingFailure = false;
236237
this._currentFailure = null;
@@ -740,7 +741,7 @@ function connect(url) {
740741
var completeUrl = host + ':' + port;
741742
var channelConfig = new _chConfig2.default(host, port, config, connectionErrorCode);
742743

743-
return new Connection(new Ch(channelConfig), completeUrl);
744+
return new Connection(new Ch(channelConfig), completeUrl, config);
744745
}
745746

746747
exports.connect = connect;

lib/v1/internal/packstream.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,13 +391,15 @@ var Packer = function () {
391391

392392

393393
var Unpacker = function () {
394-
function Unpacker() {
394+
function Unpacker(config) {
395395
(0, _classCallCheck3.default)(this, Unpacker);
396396

397397
// Higher level layers can specify how to map structs to higher-level objects.
398398
// If we recieve a struct that has a signature that does not have a mapper,
399399
// we simply return a Structure object.
400400
this.structMappers = {};
401+
402+
this._convertToString = config && config.convertToString;
401403
}
402404

403405
(0, _createClass3.default)(Unpacker, [{
@@ -418,7 +420,7 @@ var Unpacker = function () {
418420

419421
var number = this._unpackNumber(marker, buffer);
420422
if (number !== null) {
421-
return number;
423+
return !this._convertToString ? number : number.toString();
422424
}
423425

424426
var string = this._unpackString(marker, markerHigh, markerLow, buffer);

lib/v1/routing-driver.js

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ var RoutingDriver = function (_Driver) {
7575
var config = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
7676
(0, _classCallCheck3.default)(this, RoutingDriver);
7777

78-
var _this = (0, _possibleConstructorReturn3.default)(this, (RoutingDriver.__proto__ || (0, _getPrototypeOf2.default)(RoutingDriver)).call(this, url, userAgent, token, RoutingDriver._validateConfig(config)));
78+
var _this = (0, _possibleConstructorReturn3.default)(this, (RoutingDriver.__proto__ || (0, _getPrototypeOf2.default)(RoutingDriver)).call(this, url, userAgent, token, validateConfig(config)));
7979

8080
_this._routingContext = routingContext;
8181
return _this;
@@ -93,16 +93,18 @@ var RoutingDriver = function (_Driver) {
9393
var _this2 = this;
9494

9595
return new RoutingSession(mode, connectionProvider, bookmark, config, function (error, conn) {
96-
if (error.code === _error.SESSION_EXPIRED) {
97-
_this2._forgetConnection(conn);
96+
if (!conn) {
97+
// connection can be undefined if error happened before connection was acquired
9898
return error;
99-
} else if (RoutingDriver._isFailureToWrite(error)) {
100-
var url = 'UNKNOWN';
101-
// connection is undefined if error happened before connection was acquired
102-
if (conn) {
103-
url = conn.url;
104-
_this2._connectionProvider.forgetWriter(conn.url);
105-
}
99+
}
100+
101+
var url = conn.url;
102+
103+
if (error.code === _error.SESSION_EXPIRED || isDatabaseUnavailable(error)) {
104+
_this2._connectionProvider.forget(url);
105+
return error;
106+
} else if (isFailureToWrite(error)) {
107+
_this2._connectionProvider.forgetWriter(url);
106108
return (0, _error.newError)('No longer possible to write to server at ' + url, _error.SESSION_EXPIRED);
107109
} else {
108110
return error;
@@ -116,36 +118,16 @@ var RoutingDriver = function (_Driver) {
116118
// result in SESSION_EXPIRED because there might still exist other servers capable of serving the request
117119
return _error.SESSION_EXPIRED;
118120
}
119-
}, {
120-
key: '_forgetConnection',
121-
value: function _forgetConnection(connection) {
122-
// connection is undefined if error happened before connection was acquired
123-
if (connection) {
124-
this._connectionProvider.forget(connection.url);
125-
}
126-
}
127-
}], [{
128-
key: '_validateConfig',
129-
value: function _validateConfig(config) {
130-
if (config.trust === 'TRUST_ON_FIRST_USE') {
131-
throw (0, _error.newError)('The chosen trust mode is not compatible with a routing driver');
132-
}
133-
return config;
134-
}
135-
}, {
136-
key: '_isFailureToWrite',
137-
value: function _isFailureToWrite(error) {
138-
return error.code === 'Neo.ClientError.Cluster.NotALeader' || error.code === 'Neo.ClientError.General.ForbiddenOnReadOnlyDatabase';
139-
}
140121

141122
/**
142123
* Create new load balancing strategy based on the config.
143124
* @param {object} config the user provided config.
144125
* @param {Pool} connectionPool the connection pool for this driver.
145126
* @return {LoadBalancingStrategy} new strategy.
127+
* @private
146128
*/
147129

148-
}, {
130+
}], [{
149131
key: '_createLoadBalancingStrategy',
150132
value: function _createLoadBalancingStrategy(config, connectionPool) {
151133
var configuredValue = config.loadBalancingStrategy;
@@ -161,6 +143,36 @@ var RoutingDriver = function (_Driver) {
161143
return RoutingDriver;
162144
}(_driver.Driver);
163145

146+
/**
147+
* @private
148+
*/
149+
150+
151+
function validateConfig(config) {
152+
if (config.trust === 'TRUST_ON_FIRST_USE') {
153+
throw (0, _error.newError)('The chosen trust mode is not compatible with a routing driver');
154+
}
155+
return config;
156+
}
157+
158+
/**
159+
* @private
160+
*/
161+
function isFailureToWrite(error) {
162+
return error.code === 'Neo.ClientError.Cluster.NotALeader' || error.code === 'Neo.ClientError.General.ForbiddenOnReadOnlyDatabase';
163+
}
164+
165+
/**
166+
* @private
167+
*/
168+
function isDatabaseUnavailable(error) {
169+
return error.code === 'Neo.TransientError.General.DatabaseUnavailable';
170+
}
171+
172+
/**
173+
* @private
174+
*/
175+
164176
var RoutingSession = function (_Session) {
165177
(0, _inherits3.default)(RoutingSession, _Session);
166178

src/v1/internal/connector.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class Connection {
166166
* callback property
167167
* @param url - url to connect to
168168
*/
169-
constructor (channel, url) {
169+
constructor (channel, url, config) {
170170
/**
171171
* An ordered queue of observers, each exchange response (zero or more
172172
* RECORD messages followed by a SUCCESS message) we recieve will be routed
@@ -181,7 +181,7 @@ class Connection {
181181
this._dechunker = new Dechunker();
182182
this._chunker = new Chunker( channel );
183183
this._packer = new Packer( this._chunker );
184-
this._unpacker = new Unpacker();
184+
this._unpacker = new Unpacker(config);
185185

186186
this._isHandlingFailure = false;
187187
this._currentFailure = null;
@@ -591,7 +591,7 @@ function connect(url, config = {}, connectionErrorCode = null) {
591591
const completeUrl = host + ':' + port;
592592
const channelConfig = new ChannelConfig(host, port, config, connectionErrorCode);
593593

594-
return new Connection( new Ch(channelConfig), completeUrl);
594+
return new Connection( new Ch(channelConfig), completeUrl, config);
595595
}
596596

597597
export {

src/v1/internal/packstream.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,13 @@ class Packer {
309309
* @access private
310310
*/
311311
class Unpacker {
312-
constructor () {
312+
constructor (config) {
313313
// Higher level layers can specify how to map structs to higher-level objects.
314314
// If we recieve a struct that has a signature that does not have a mapper,
315315
// we simply return a Structure object.
316316
this.structMappers = {};
317+
318+
this._convertToString = config && config.convertToString
317319
}
318320

319321
unpack(buffer) {
@@ -332,7 +334,7 @@ class Unpacker {
332334

333335
const number = this._unpackNumber(marker, buffer);
334336
if (number !== null) {
335-
return number;
337+
return !this._convertToString ? number : number.toString();
336338
}
337339

338340
const string = this._unpackString(marker, markerHigh, markerLow, buffer);

0 commit comments

Comments
 (0)