UNPKG

5.68 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const GetClusterTopologyCommand_1 = require("../ServerWide/Commands/GetClusterTopologyCommand");
4const NodeSelector_1 = require("./NodeSelector");
5const os = require("os");
6const BluebirdPromise = require("bluebird");
7const semaphore = require("semaphore");
8const LogUtil_1 = require("../Utility/LogUtil");
9const RequestExecutor_1 = require("./RequestExecutor");
10const __1 = require("..");
11const Exceptions_1 = require("../Exceptions");
12const ServerNode_1 = require("./ServerNode");
13const Topology_1 = require("./Topology");
14const GetTcpInfoCommand_1 = require("../ServerWide/Commands/GetTcpInfoCommand");
15const SemaphoreUtil_1 = require("../Utility/SemaphoreUtil");
16const log = LogUtil_1.getLogger({ module: "ClusterRequestExecutor" });
17class ClusterRequestExecutor extends RequestExecutor_1.RequestExecutor {
18 constructor(authOptions, conventions) {
19 super(null, authOptions, conventions);
20 this._clusterTopologySemaphore = semaphore();
21 }
22 static createForSingleNodeWithConfigurationUpdates(url, databaseName, opts) {
23 return Exceptions_1.throwError("NotSupportedException");
24 }
25 static createForSingleNodeWithoutConfigurationUpdates(url, databaseName, opts) {
26 return Exceptions_1.throwError("NotSupportedException");
27 }
28 static createForSingleNode(url, opts) {
29 const initialUrls = [url];
30 const { authOptions, documentConventions } = opts;
31 const urls = this._validateUrls(initialUrls, authOptions);
32 const executor = new ClusterRequestExecutor(authOptions, documentConventions || __1.DocumentConventions.defaultConventions);
33 const serverNode = new ServerNode_1.ServerNode({ url });
34 const topology = new Topology_1.Topology(-1, [serverNode]);
35 const nodeSelector = new NodeSelector_1.NodeSelector(topology);
36 executor._nodeSelector = nodeSelector;
37 executor._topologyEtag = -2;
38 executor._disableClientConfigurationUpdates = true;
39 executor._disableTopologyUpdates = true;
40 return executor;
41 }
42 static create(initialUrls, databaseOrOpts, opts) {
43 if (typeof (databaseOrOpts) === "string") {
44 return Exceptions_1.throwError("NotSupportedException");
45 }
46 const { authOptions, documentConventions } = (opts || databaseOrOpts) || {};
47 const executor = new ClusterRequestExecutor(authOptions, documentConventions ? documentConventions : __1.DocumentConventions.defaultConventions);
48 executor._disableClientConfigurationUpdates = true;
49 executor._firstTopologyUpdatePromise = executor._firstTopologyUpdate(initialUrls);
50 return executor;
51 }
52 _performHealthCheck(serverNode, nodeIndex) {
53 return this.execute(new GetTcpInfoCommand_1.GetTcpInfoCommand("health-check"), null, {
54 chosenNode: serverNode,
55 nodeIndex,
56 shouldRetry: false
57 });
58 }
59 updateTopology(node, timeout, forceUpdate) {
60 if (this._disposed) {
61 return Promise.resolve(false);
62 }
63 const acquiredSemContext = SemaphoreUtil_1.acquireSemaphore(this._clusterTopologySemaphore, { timeout });
64 const result = BluebirdPromise.resolve(acquiredSemContext.promise)
65 .then(() => {
66 if (this._disposed) {
67 return false;
68 }
69 const command = new GetClusterTopologyCommand_1.GetClusterTopologyCommand();
70 return this.execute(command, null, {
71 chosenNode: node,
72 nodeIndex: null,
73 shouldRetry: false
74 })
75 .then(() => {
76 const results = command.result;
77 const members = results.topology.members;
78 const nodes = Object.keys(members)
79 .reduce((reduceResult, clusterTag) => {
80 const url = members[clusterTag];
81 const serverNode = new ServerNode_1.ServerNode({ clusterTag, url });
82 return [...reduceResult, serverNode];
83 }, []);
84 const newTopology = new Topology_1.Topology(0, nodes);
85 if (!this._nodeSelector) {
86 this._nodeSelector = new NodeSelector_1.NodeSelector(newTopology);
87 if (this._readBalanceBehavior === "FastestNode") {
88 this._nodeSelector.scheduleSpeedTest();
89 }
90 }
91 else if (this._nodeSelector.onUpdateTopology(newTopology, forceUpdate)) {
92 this._disposeAllFailedNodesTimers();
93 if (this._readBalanceBehavior === "FastestNode") {
94 this._nodeSelector.scheduleSpeedTest();
95 }
96 }
97 })
98 .then(() => true);
99 }, (reason) => {
100 if (reason.name === "TimeoutError") {
101 return false;
102 }
103 throw reason;
104 })
105 .finally(() => acquiredSemContext.dispose());
106 return Promise.resolve(result);
107 }
108 _updateClientConfigurationAsync() {
109 return Promise.resolve();
110 }
111 _throwExceptions(details) {
112 Exceptions_1.throwError("InvalidOperationException", "Failed to retrieve cluster topology from all known nodes" + os.EOL + details);
113 }
114 dispose() {
115 this._clusterTopologySemaphore.take(() => {
116 });
117 super.dispose();
118 }
119}
120exports.ClusterRequestExecutor = ClusterRequestExecutor;