ravendb
Version:
RavenDB client for Node.js
109 lines • 4.88 kB
JavaScript
import { GetClusterTopologyCommand } from "../ServerWide/Commands/GetClusterTopologyCommand.js";
import { NodeSelector } from "./NodeSelector.js";
import { getLogger } from "../Utility/LogUtil.js";
import { RequestExecutor } from "./RequestExecutor.js";
import { throwError } from "../Exceptions/index.js";
import { ServerNode } from "./ServerNode.js";
import { Topology } from "./Topology.js";
import { GetTcpInfoCommand } from "../ServerWide/Commands/GetTcpInfoCommand.js";
import { acquireSemaphore } from "../Utility/SemaphoreUtil.js";
import { DocumentConventions } from "../Documents/Conventions/DocumentConventions.js";
import { HEADERS } from "../Constants.js";
import { Semaphore } from "../Utility/Semaphore.js";
import { EOL } from "../Utility/OsUtil.js";
const log = getLogger({ module: "ClusterRequestExecutor" });
export class ClusterRequestExecutor extends RequestExecutor {
_clusterTopologySemaphore = new Semaphore();
constructor(authOptions, conventions) {
super(null, authOptions, conventions);
}
static createForSingleNodeWithConfigurationUpdates(url, databaseName, opts) {
return throwError("NotSupportedException");
}
static createForSingleNodeWithoutConfigurationUpdates(url, databaseName, opts) {
return throwError("NotSupportedException");
}
static createForSingleNode(url, opts) {
const initialUrls = [url];
const { authOptions, documentConventions } = opts;
const urls = this.validateUrls(initialUrls, authOptions);
const executor = new ClusterRequestExecutor(authOptions, documentConventions || DocumentConventions.defaultConventions);
const serverNode = new ServerNode({ url: urls[0], serverRole: "Member" });
const topology = new Topology(-1, [serverNode]);
const nodeSelector = new NodeSelector(topology);
executor._nodeSelector = nodeSelector;
executor._topologyEtag = -2;
executor._disableClientConfigurationUpdates = true;
executor._disableTopologyUpdates = true;
executor._topologyHeaderName = HEADERS.CLUSTER_TOPOLOGY_ETAG;
executor.firstTopologyUpdatePromise = executor._singleTopologyUpdateAsync(urls, null);
return executor;
}
static create(initialUrls, databaseOrOpts, opts) {
if (typeof (databaseOrOpts) === "string") {
return throwError("NotSupportedException");
}
const { authOptions, documentConventions } = (opts || databaseOrOpts) || {};
const executor = new ClusterRequestExecutor(authOptions, documentConventions ?? DocumentConventions.defaultConventions);
executor._disableClientConfigurationUpdates = true;
executor.firstTopologyUpdatePromise = executor._firstTopologyUpdate(initialUrls, null);
executor._topologyHeaderName = HEADERS.CLUSTER_TOPOLOGY_ETAG;
return executor;
}
_performHealthCheck(serverNode, nodeIndex) {
return this.execute(new GetTcpInfoCommand("health-check"), null, {
chosenNode: serverNode,
nodeIndex,
shouldRetry: false
});
}
async updateTopology(parameters) {
if (this._disposed) {
return false;
}
if (this._disableTopologyUpdates) {
return false;
}
const acquiredSemContext = acquireSemaphore(this._clusterTopologySemaphore, { timeout: parameters.timeoutInMs });
try {
await acquiredSemContext.promise;
if (this._disposed) {
return false;
}
const command = new GetClusterTopologyCommand(parameters.debugTag);
await this.execute(command, null, {
chosenNode: parameters.node,
nodeIndex: null,
shouldRetry: false
});
const results = command.result;
const newTopology = ServerNode.createFrom(results.topology, results.etag);
this._updateNodeSelector(newTopology, parameters.forceUpdate);
this._onTopologyUpdatedInvoke(newTopology, parameters.debugTag);
return true;
}
catch (reason) {
if (reason.name === "TimeoutError") {
return false;
}
throw reason;
}
finally {
acquiredSemContext.dispose();
}
}
_updateClientConfigurationAsync(serverNode) {
return Promise.resolve();
}
_throwExceptions(details) {
throwError("InvalidOperationException", "Failed to retrieve cluster topology from all known nodes" + EOL + details);
}
dispose() {
// eslint-disable-next-line @typescript-eslint/no-empty-function
this._clusterTopologySemaphore.take(() => {
// empty
});
super.dispose();
}
}
//# sourceMappingURL=ClusterRequestExecutor.js.map