UNPKG

ravendb

Version:
124 lines 5.39 kB
import { ClusterRequestExecutor } from "../../Http/ClusterRequestExecutor.js"; import { ServerWideOperationCompletionAwaiter } from "../../ServerWide/Operations/ServerWideOperationCompletionAwaiter.js"; import { getLogger } from "../../Utility/LogUtil.js"; import { throwError } from "../../Exceptions/index.js"; import { StringUtil } from "../../Utility/StringUtil.js"; import { GetBuildNumberOperation } from "../../ServerWide/Operations/GetBuildNumberOperation.js"; const log = getLogger({ module: "ServerOperationExecutor" }); export class ServerOperationExecutor { _cache; _nodeTag; _store; _requestExecutor; _initialRequestExecutor; constructor(store, requestExecutor, initialRequestExecutor, cache, nodeTag) { requestExecutor = requestExecutor || ServerOperationExecutor._createRequestExecutor(store); cache = cache || new Map(); if (!store) { throwError("InvalidArgumentException", "Store cannot be null"); } if (!requestExecutor) { 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.isNullOrWhitespace(nodeTag)) { throwError("InvalidArgumentException", "Value cannot be null or whitespace."); } if ((!nodeTag && !this._nodeTag) || StringUtil.equalsIgnoreCase(this._nodeTag, nodeTag)) { return this; } if (this._store.conventions.disableTopologyUpdates) { 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.equalsIgnoreCase(x.clusterTag, nodeTag)); if (!node) { const availableNodes = topology .nodes .map(x => x.clusterTag) .join(", "); throwError("InvalidOperationException", "Could not find node '" + nodeTag + "' in the topology. Available nodes: " + availableNodes); } const clusterExecutor = 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(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(); const command = operation.getCommand(requestExecutor.conventions); await requestExecutor.execute(command); topology = requestExecutor.getTopology(); } } catch { // ignored } if (!topology) { 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.createForSingleNode(store.urls[0], args) : ClusterRequestExecutor.create(store.urls, args); } } //# sourceMappingURL=ServerOperationExecutor.js.map