@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
125 lines (124 loc) • 5.15 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var timeoutFailoverRetryPolicy_exports = {};
__export(timeoutFailoverRetryPolicy_exports, {
TimeoutFailoverRetryPolicy: () => TimeoutFailoverRetryPolicy
});
module.exports = __toCommonJS(timeoutFailoverRetryPolicy_exports);
var import_statusCodes = require("../common/statusCodes.js");
var import_common = require("../common/index.js");
var import_constants = require("../common/constants.js");
var import_TimeoutError = require("../request/TimeoutError.js");
class TimeoutFailoverRetryPolicy {
constructor(globalEndpointManager, headers, methodType, resourceType, operationType, enableEndPointDiscovery, globalPartitionEndpointManager) {
this.globalEndpointManager = globalEndpointManager;
this.headers = headers;
this.methodType = methodType;
this.resourceType = resourceType;
this.operationType = operationType;
this.enableEndPointDiscovery = enableEndPointDiscovery;
this.globalPartitionEndpointManager = globalPartitionEndpointManager;
}
maxRetryAttemptCount = 120;
maxServiceUnavailableRetryCount = 1;
retryAfterInMs = 0;
failoverRetryCount = 0;
request;
locationEndpoint;
/**
* Checks if a timeout request is valid for the timeout failover retry policy.
* A valid request should be a data plane, metadata, or query plan request.
* @returns
*/
isValidRequestForTimeoutError() {
const isQuery = import_constants.Constants.HttpHeaders.IsQuery in this.headers;
const isQueryPlan = import_constants.Constants.HttpHeaders.IsQueryPlan in this.headers;
if (this.methodType === import_common.HTTPMethod.get || isQuery || isQueryPlan) {
return true;
}
return false;
}
async shouldRetry(err, diagnosticNode, retryContext, locationEndpoint, requestContext) {
if (!err) {
return false;
}
if (!retryContext || !locationEndpoint) {
return false;
}
if (!this.enableEndPointDiscovery) {
return false;
}
if (requestContext && this.globalPartitionEndpointManager) {
await this.globalPartitionEndpointManager.tryPartitionLevelFailover(
requestContext,
diagnosticNode
);
}
if (err.code === import_TimeoutError.TimeoutErrorCode && !this.isValidRequestForTimeoutError()) {
return false;
}
if (err.code === import_statusCodes.StatusCodes.ServiceUnavailable && this.failoverRetryCount >= this.maxServiceUnavailableRetryCount) {
return false;
}
if (this.failoverRetryCount >= this.maxRetryAttemptCount) {
return false;
}
const canUseMultipleWriteLocations = this.globalEndpointManager.canUseMultipleWriteLocations(
this.resourceType,
this.operationType
);
const readRequest = (0, import_common.isReadRequest)(this.operationType);
if (!canUseMultipleWriteLocations && !readRequest && !this.globalPartitionEndpointManager?.isPartitionLevelAutomaticFailoverEnabled()) {
return false;
}
this.failoverRetryCount++;
retryContext.retryLocationServerIndex = await this.findEndpointIndex(this.failoverRetryCount);
diagnosticNode.addData({ successfulRetryPolicy: "timeout-failover" });
return true;
}
/**
* Determines index of endpoint to be used for retry based upon failoverRetryCount and avalable locations
* @param failoverRetryCount - count of failovers
* @returns
*/
async findEndpointIndex(failoverRetryCount) {
const preferredLocationsCount = this.globalEndpointManager.preferredLocationsCount;
const readRequest = (0, import_common.isReadRequest)(this.operationType);
let endpointIndex = 0;
if (preferredLocationsCount !== 0) {
endpointIndex = failoverRetryCount % preferredLocationsCount;
} else {
if (readRequest) {
const getReadEndpoints = await this.globalEndpointManager.getReadEndpoints();
if (getReadEndpoints && getReadEndpoints.length > 0) {
endpointIndex = failoverRetryCount % getReadEndpoints.length;
}
} else {
const getWriteEndpoints = await this.globalEndpointManager.getWriteEndpoints();
if (getWriteEndpoints && getWriteEndpoints.length > 0) {
endpointIndex = failoverRetryCount % getWriteEndpoints.length;
}
}
}
return endpointIndex;
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
TimeoutFailoverRetryPolicy
});