ravendb
Version:
RavenDB client for Node.js
128 lines • 5.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServerOperationExecutor = void 0;
const ClusterRequestExecutor_js_1 = require("../../Http/ClusterRequestExecutor.js");
const ServerWideOperationCompletionAwaiter_js_1 = require("../../ServerWide/Operations/ServerWideOperationCompletionAwaiter.js");
const LogUtil_js_1 = require("../../Utility/LogUtil.js");
const index_js_1 = require("../../Exceptions/index.js");
const StringUtil_js_1 = require("../../Utility/StringUtil.js");
const GetBuildNumberOperation_js_1 = require("../../ServerWide/Operations/GetBuildNumberOperation.js");
const log = (0, LogUtil_js_1.getLogger)({ module: "ServerOperationExecutor" });
class ServerOperationExecutor {
_cache;
_nodeTag;
_store;
_requestExecutor;
_initialRequestExecutor;
constructor(store, requestExecutor, initialRequestExecutor, cache, nodeTag) {
requestExecutor = requestExecutor || ServerOperationExecutor._createRequestExecutor(store);
cache = cache || new Map();
if (!store) {
(0, index_js_1.throwError)("InvalidArgumentException", "Store cannot be null");
}
if (!requestExecutor) {
(0, index_js_1.throwError)("InvalidArgumentException", "RequestExecutor cannot be null");
}
this._store = store;
this._requestExecutor = requestExecutor;
this._initialRequestExecutor = initialRequestExecutor;
this._nodeTag = nodeTag;
this._cache = cache;
store.registerEvents(this._requestExecutor);
if (!nodeTag) {
store.once("afterDispose", (callback) => {
log.info("Dispose request executor.");
this._requestExecutor.dispose();
callback();
});
}
}
async forNode(nodeTag) {
if (StringUtil_js_1.StringUtil.isNullOrWhitespace(nodeTag)) {
(0, index_js_1.throwError)("InvalidArgumentException", "Value cannot be null or whitespace.");
}
if ((!nodeTag && !this._nodeTag) || StringUtil_js_1.StringUtil.equalsIgnoreCase(this._nodeTag, nodeTag)) {
return this;
}
if (this._store.conventions.disableTopologyUpdates) {
(0, index_js_1.throwError)("InvalidOperationException", "Cannot switch server operation executor, because conventions.disableTopologyUpdates is set to 'true'");
}
const existingValue = this._cache.get(nodeTag.toLowerCase());
if (existingValue) {
return existingValue;
}
const requestExecutor = this._initialRequestExecutor || this._requestExecutor;
const topology = await this._getTopology(requestExecutor);
const node = topology.nodes
.find(x => StringUtil_js_1.StringUtil.equalsIgnoreCase(x.clusterTag, nodeTag));
if (!node) {
const availableNodes = topology
.nodes
.map(x => x.clusterTag)
.join(", ");
(0, index_js_1.throwError)("InvalidOperationException", "Could not find node '" + nodeTag + "' in the topology. Available nodes: " + availableNodes);
}
const clusterExecutor = ClusterRequestExecutor_js_1.ClusterRequestExecutor.createForSingleNode(node.url, {
authOptions: this._store.authOptions
});
return new ServerOperationExecutor(this._store, clusterExecutor, requestExecutor, this._cache, node.clusterTag);
}
async send(operation) {
const command = operation.getCommand(this._requestExecutor.conventions);
await this._requestExecutor.execute(command);
if (operation.resultType === "OperationId") {
const idResult = command.result;
return new ServerWideOperationCompletionAwaiter_js_1.ServerWideOperationCompletionAwaiter(this._requestExecutor, this._requestExecutor.conventions, idResult.operationId, command.selectedNodeTag || idResult.operationNodeTag);
}
return command.result;
}
dispose() {
if (this._nodeTag) {
return;
}
if (this._requestExecutor) {
this._requestExecutor.dispose();
}
if (this._cache) {
for (const [key, value] of this._cache.entries()) {
const requestExecutor = value._requestExecutor;
if (requestExecutor) {
requestExecutor.dispose();
}
}
this._cache.clear();
}
}
async _getTopology(requestExecutor) {
let topology = null;
try {
topology = requestExecutor.getTopology();
if (!topology) {
// a bit rude way to make sure that topology has been refreshed
// but it handles a case when first topology update failed
const operation = new GetBuildNumberOperation_js_1.GetBuildNumberOperation();
const command = operation.getCommand(requestExecutor.conventions);
await requestExecutor.execute(command);
topology = requestExecutor.getTopology();
}
}
catch {
// ignored
}
if (!topology) {
(0, index_js_1.throwError)("InvalidOperationException", "Could not fetch the topology");
}
return topology;
}
static _createRequestExecutor(store) {
const args = {
authOptions: store.authOptions,
documentConventions: store.conventions
};
return store.conventions.disableTopologyUpdates
? ClusterRequestExecutor_js_1.ClusterRequestExecutor.createForSingleNode(store.urls[0], args)
: ClusterRequestExecutor_js_1.ClusterRequestExecutor.create(store.urls, args);
}
}
exports.ServerOperationExecutor = ServerOperationExecutor;
//# sourceMappingURL=ServerOperationExecutor.js.map