UNPKG

@azure/cosmos

Version:
125 lines (124 loc) 5.15 kB
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 });