UNPKG

6.94 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
8
9var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
10
11var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
12
13var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
14
15var _createClass2 = require('babel-runtime/helpers/createClass');
16
17var _createClass3 = _interopRequireDefault(_createClass2);
18
19var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
20
21var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
22
23var _inherits2 = require('babel-runtime/helpers/inherits');
24
25var _inherits3 = _interopRequireDefault(_inherits2);
26
27var _session = require('./session');
28
29var _session2 = _interopRequireDefault(_session);
30
31var _driver = require('./driver');
32
33var _error = require('./error');
34
35var _connectionProviders = require('./internal/connection-providers');
36
37var _leastConnectedLoadBalancingStrategy = require('./internal/least-connected-load-balancing-strategy');
38
39var _leastConnectedLoadBalancingStrategy2 = _interopRequireDefault(_leastConnectedLoadBalancingStrategy);
40
41var _roundRobinLoadBalancingStrategy = require('./internal/round-robin-load-balancing-strategy');
42
43var _roundRobinLoadBalancingStrategy2 = _interopRequireDefault(_roundRobinLoadBalancingStrategy);
44
45function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
46
47/**
48 * A driver that supports routing in a causal cluster.
49 * @private
50 */
51/**
52 * Copyright (c) 2002-2018 Neo4j Sweden AB [http://neo4j.com]
53 *
54 * This file is part of Neo4j.
55 *
56 * Licensed under the Apache License, Version 2.0 (the "License");
57 * you may not use this file except in compliance with the License.
58 * You may obtain a copy of the License at
59 *
60 * http://www.apache.org/licenses/LICENSE-2.0
61 *
62 * Unless required by applicable law or agreed to in writing, software
63 * distributed under the License is distributed on an "AS IS" BASIS,
64 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65 * See the License for the specific language governing permissions and
66 * limitations under the License.
67 */
68
69var RoutingDriver = function (_Driver) {
70 (0, _inherits3.default)(RoutingDriver, _Driver);
71
72 function RoutingDriver(hostPort, routingContext, userAgent) {
73 var token = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
74 var config = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
75 (0, _classCallCheck3.default)(this, RoutingDriver);
76
77 var _this = (0, _possibleConstructorReturn3.default)(this, (RoutingDriver.__proto__ || (0, _getPrototypeOf2.default)(RoutingDriver)).call(this, hostPort, userAgent, token, validateConfig(config)));
78
79 _this._routingContext = routingContext;
80 return _this;
81 }
82
83 (0, _createClass3.default)(RoutingDriver, [{
84 key: '_createConnectionProvider',
85 value: function _createConnectionProvider(hostPort, connectionPool, driverOnErrorCallback) {
86 var loadBalancingStrategy = RoutingDriver._createLoadBalancingStrategy(this._config, connectionPool);
87 return new _connectionProviders.LoadBalancer(hostPort, this._routingContext, connectionPool, loadBalancingStrategy, driverOnErrorCallback);
88 }
89 }, {
90 key: '_createSession',
91 value: function _createSession(mode, connectionProvider, bookmark, config) {
92 var _this2 = this;
93
94 return new RoutingSession(mode, connectionProvider, bookmark, config, function (error, conn) {
95 if (!conn) {
96 // connection can be undefined if error happened before connection was acquired
97 return error;
98 }
99
100 var hostPort = conn.hostPort;
101
102 if (error.code === _error.SESSION_EXPIRED || isDatabaseUnavailable(error)) {
103 _this2._connectionProvider.forget(hostPort);
104 return error;
105 } else if (isFailureToWrite(error)) {
106 _this2._connectionProvider.forgetWriter(hostPort);
107 return (0, _error.newError)('No longer possible to write to server at ' + hostPort, _error.SESSION_EXPIRED);
108 } else {
109 return error;
110 }
111 });
112 }
113 }, {
114 key: '_connectionErrorCode',
115 value: function _connectionErrorCode() {
116 // connection errors mean SERVICE_UNAVAILABLE for direct driver but for routing driver they should only
117 // result in SESSION_EXPIRED because there might still exist other servers capable of serving the request
118 return _error.SESSION_EXPIRED;
119 }
120
121 /**
122 * Create new load balancing strategy based on the config.
123 * @param {object} config the user provided config.
124 * @param {Pool} connectionPool the connection pool for this driver.
125 * @return {LoadBalancingStrategy} new strategy.
126 * @private
127 */
128
129 }], [{
130 key: '_createLoadBalancingStrategy',
131 value: function _createLoadBalancingStrategy(config, connectionPool) {
132 var configuredValue = config.loadBalancingStrategy;
133 if (!configuredValue || configuredValue === _leastConnectedLoadBalancingStrategy.LEAST_CONNECTED_STRATEGY_NAME) {
134 return new _leastConnectedLoadBalancingStrategy2.default(connectionPool);
135 } else if (configuredValue === _roundRobinLoadBalancingStrategy.ROUND_ROBIN_STRATEGY_NAME) {
136 return new _roundRobinLoadBalancingStrategy2.default();
137 } else {
138 throw (0, _error.newError)('Unknown load balancing strategy: ' + configuredValue);
139 }
140 }
141 }]);
142 return RoutingDriver;
143}(_driver.Driver);
144
145/**
146 * @private
147 */
148
149
150function validateConfig(config) {
151 if (config.trust === 'TRUST_ON_FIRST_USE') {
152 throw (0, _error.newError)('The chosen trust mode is not compatible with a routing driver');
153 }
154 return config;
155}
156
157/**
158 * @private
159 */
160function isFailureToWrite(error) {
161 return error.code === 'Neo.ClientError.Cluster.NotALeader' || error.code === 'Neo.ClientError.General.ForbiddenOnReadOnlyDatabase';
162}
163
164/**
165 * @private
166 */
167function isDatabaseUnavailable(error) {
168 return error.code === 'Neo.TransientError.General.DatabaseUnavailable';
169}
170
171/**
172 * @private
173 */
174
175var RoutingSession = function (_Session) {
176 (0, _inherits3.default)(RoutingSession, _Session);
177
178 function RoutingSession(mode, connectionProvider, bookmark, config, onFailedConnection) {
179 (0, _classCallCheck3.default)(this, RoutingSession);
180
181 var _this3 = (0, _possibleConstructorReturn3.default)(this, (RoutingSession.__proto__ || (0, _getPrototypeOf2.default)(RoutingSession)).call(this, mode, connectionProvider, bookmark, config));
182
183 _this3._onFailedConnection = onFailedConnection;
184 return _this3;
185 }
186
187 (0, _createClass3.default)(RoutingSession, [{
188 key: '_onRunFailure',
189 value: function _onRunFailure() {
190 return this._onFailedConnection;
191 }
192 }]);
193 return RoutingSession;
194}(_session2.default);
195
196exports.default = RoutingDriver;
\No newline at end of file