197 lines
6.8 KiB
JavaScript
197 lines
6.8 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
|
|
|
|
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
|
|
|
|
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
|
|
|
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
|
|
|
var _createClass2 = require('babel-runtime/helpers/createClass');
|
|
|
|
var _createClass3 = _interopRequireDefault(_createClass2);
|
|
|
|
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
|
|
|
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
|
|
|
var _inherits2 = require('babel-runtime/helpers/inherits');
|
|
|
|
var _inherits3 = _interopRequireDefault(_inherits2);
|
|
|
|
var _session = require('./session');
|
|
|
|
var _session2 = _interopRequireDefault(_session);
|
|
|
|
var _driver = require('./driver');
|
|
|
|
var _error = require('./error');
|
|
|
|
var _connectionProviders = require('./internal/connection-providers');
|
|
|
|
var _leastConnectedLoadBalancingStrategy = require('./internal/least-connected-load-balancing-strategy');
|
|
|
|
var _leastConnectedLoadBalancingStrategy2 = _interopRequireDefault(_leastConnectedLoadBalancingStrategy);
|
|
|
|
var _roundRobinLoadBalancingStrategy = require('./internal/round-robin-load-balancing-strategy');
|
|
|
|
var _roundRobinLoadBalancingStrategy2 = _interopRequireDefault(_roundRobinLoadBalancingStrategy);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* A driver that supports routing in a causal cluster.
|
|
* @private
|
|
*/
|
|
/**
|
|
* Copyright (c) 2002-2018 "Neo4j,"
|
|
* Neo4j Sweden AB [http://neo4j.com]
|
|
*
|
|
* This file is part of Neo4j.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
var RoutingDriver = function (_Driver) {
|
|
(0, _inherits3.default)(RoutingDriver, _Driver);
|
|
|
|
function RoutingDriver(hostPort, routingContext, userAgent) {
|
|
var token = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
var config = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
(0, _classCallCheck3.default)(this, RoutingDriver);
|
|
|
|
var _this = (0, _possibleConstructorReturn3.default)(this, (RoutingDriver.__proto__ || (0, _getPrototypeOf2.default)(RoutingDriver)).call(this, hostPort, userAgent, token, validateConfig(config)));
|
|
|
|
_this._routingContext = routingContext;
|
|
return _this;
|
|
}
|
|
|
|
(0, _createClass3.default)(RoutingDriver, [{
|
|
key: '_createConnectionProvider',
|
|
value: function _createConnectionProvider(hostPort, connectionPool, driverOnErrorCallback) {
|
|
var loadBalancingStrategy = RoutingDriver._createLoadBalancingStrategy(this._config, connectionPool);
|
|
return new _connectionProviders.LoadBalancer(hostPort, this._routingContext, connectionPool, loadBalancingStrategy, driverOnErrorCallback);
|
|
}
|
|
}, {
|
|
key: '_createSession',
|
|
value: function _createSession(mode, connectionProvider, bookmark, config) {
|
|
var _this2 = this;
|
|
|
|
return new RoutingSession(mode, connectionProvider, bookmark, config, function (error, conn) {
|
|
if (!conn) {
|
|
// connection can be undefined if error happened before connection was acquired
|
|
return error;
|
|
}
|
|
|
|
var hostPort = conn.hostPort;
|
|
|
|
if (error.code === _error.SESSION_EXPIRED || isDatabaseUnavailable(error)) {
|
|
_this2._connectionProvider.forget(hostPort);
|
|
return error;
|
|
} else if (isFailureToWrite(error)) {
|
|
_this2._connectionProvider.forgetWriter(hostPort);
|
|
return (0, _error.newError)('No longer possible to write to server at ' + hostPort, _error.SESSION_EXPIRED);
|
|
} else {
|
|
return error;
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: '_connectionErrorCode',
|
|
value: function _connectionErrorCode() {
|
|
// connection errors mean SERVICE_UNAVAILABLE for direct driver but for routing driver they should only
|
|
// result in SESSION_EXPIRED because there might still exist other servers capable of serving the request
|
|
return _error.SESSION_EXPIRED;
|
|
}
|
|
|
|
/**
|
|
* Create new load balancing strategy based on the config.
|
|
* @param {object} config the user provided config.
|
|
* @param {Pool} connectionPool the connection pool for this driver.
|
|
* @return {LoadBalancingStrategy} new strategy.
|
|
* @private
|
|
*/
|
|
|
|
}], [{
|
|
key: '_createLoadBalancingStrategy',
|
|
value: function _createLoadBalancingStrategy(config, connectionPool) {
|
|
var configuredValue = config.loadBalancingStrategy;
|
|
if (!configuredValue || configuredValue === _leastConnectedLoadBalancingStrategy.LEAST_CONNECTED_STRATEGY_NAME) {
|
|
return new _leastConnectedLoadBalancingStrategy2.default(connectionPool);
|
|
} else if (configuredValue === _roundRobinLoadBalancingStrategy.ROUND_ROBIN_STRATEGY_NAME) {
|
|
return new _roundRobinLoadBalancingStrategy2.default();
|
|
} else {
|
|
throw (0, _error.newError)('Unknown load balancing strategy: ' + configuredValue);
|
|
}
|
|
}
|
|
}]);
|
|
return RoutingDriver;
|
|
}(_driver.Driver);
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
|
|
|
|
function validateConfig(config) {
|
|
if (config.trust === 'TRUST_ON_FIRST_USE') {
|
|
throw (0, _error.newError)('The chosen trust mode is not compatible with a routing driver');
|
|
}
|
|
return config;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
function isFailureToWrite(error) {
|
|
return error.code === 'Neo.ClientError.Cluster.NotALeader' || error.code === 'Neo.ClientError.General.ForbiddenOnReadOnlyDatabase';
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
function isDatabaseUnavailable(error) {
|
|
return error.code === 'Neo.TransientError.General.DatabaseUnavailable';
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
|
|
var RoutingSession = function (_Session) {
|
|
(0, _inherits3.default)(RoutingSession, _Session);
|
|
|
|
function RoutingSession(mode, connectionProvider, bookmark, config, onFailedConnection) {
|
|
(0, _classCallCheck3.default)(this, RoutingSession);
|
|
|
|
var _this3 = (0, _possibleConstructorReturn3.default)(this, (RoutingSession.__proto__ || (0, _getPrototypeOf2.default)(RoutingSession)).call(this, mode, connectionProvider, bookmark, config));
|
|
|
|
_this3._onFailedConnection = onFailedConnection;
|
|
return _this3;
|
|
}
|
|
|
|
(0, _createClass3.default)(RoutingSession, [{
|
|
key: '_onRunFailure',
|
|
value: function _onRunFailure() {
|
|
return this._onFailedConnection;
|
|
}
|
|
}]);
|
|
return RoutingSession;
|
|
}(_session2.default);
|
|
|
|
exports.default = RoutingDriver; |