UNPKG

@azure/core-amqp

Version:

Common library for amqp based azure sdks like @azure/event-hubs.

176 lines (175 loc) • 6.64 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 retry_exports = {}; __export(retry_exports, { RetryMode: () => RetryMode, RetryOperationType: () => RetryOperationType, retry: () => retry }); module.exports = __toCommonJS(retry_exports); var import_errors = require("./errors.js"); var import_constants = require("./util/constants.js"); var import_checkNetworkConnection = require("./util/checkNetworkConnection.js"); var import_core_util = require("@azure/core-util"); var import_log = require("./log.js"); function isDelivery(obj) { let result = false; if (obj && typeof obj.id === "number" && typeof obj.settled === "boolean" && typeof obj.remote_settled === "boolean" && typeof obj.format === "number") { result = true; } return result; } var RetryMode = /* @__PURE__ */ ((RetryMode2) => { RetryMode2[RetryMode2["Exponential"] = 0] = "Exponential"; RetryMode2[RetryMode2["Fixed"] = 1] = "Fixed"; return RetryMode2; })(RetryMode || {}); var RetryOperationType = /* @__PURE__ */ ((RetryOperationType2) => { RetryOperationType2["cbsAuth"] = "cbsAuth"; RetryOperationType2["connection"] = "connection"; RetryOperationType2["management"] = "management"; RetryOperationType2["receiverLink"] = "receiverLink"; RetryOperationType2["senderLink"] = "senderLink"; RetryOperationType2["sendMessage"] = "sendMessage"; RetryOperationType2["receiveMessage"] = "receiveMessage"; RetryOperationType2["session"] = "session"; RetryOperationType2["messageSettlement"] = "settlement"; return RetryOperationType2; })(RetryOperationType || {}); function validateRetryConfig(config) { if (!config.operation) { throw new TypeError("Missing 'operation' in retry configuration"); } if (!config.connectionId) { throw new TypeError("Missing 'connectionId' in retry configuration"); } if (!config.operationType) { throw new TypeError("Missing 'operationType' in retry configuration"); } } function calculateDelay(attemptCount, retryDelayInMs, maxRetryDelayInMs, mode) { if (mode === 0 /* Exponential */) { const boundedRandDelta = retryDelayInMs * 0.8 + Math.floor(Math.random() * (retryDelayInMs * 1.2 - retryDelayInMs * 0.8)); const incrementDelta = boundedRandDelta * (Math.pow(2, attemptCount) - 1); return Math.min(incrementDelta, maxRetryDelayInMs); } return retryDelayInMs; } async function retry(config) { validateRetryConfig(config); const updatedConfig = { ...config }; if (!updatedConfig.retryOptions) { updatedConfig.retryOptions = {}; } if (updatedConfig.retryOptions.maxRetries == void 0 || updatedConfig.retryOptions.maxRetries < 0) { updatedConfig.retryOptions.maxRetries = import_constants.Constants.defaultMaxRetries; } if (updatedConfig.retryOptions.retryDelayInMs == void 0 || updatedConfig.retryOptions.retryDelayInMs < 0) { updatedConfig.retryOptions.retryDelayInMs = import_constants.Constants.defaultDelayBetweenOperationRetriesInMs; } if (updatedConfig.retryOptions.maxRetryDelayInMs == void 0 || updatedConfig.retryOptions.maxRetryDelayInMs < 0) { updatedConfig.retryOptions.maxRetryDelayInMs = import_constants.Constants.defaultMaxDelayForExponentialRetryInMs; } if (updatedConfig.retryOptions.mode == void 0) { updatedConfig.retryOptions.mode = 1 /* Fixed */; } const errors = []; let result; let success = false; const totalNumberOfAttempts = updatedConfig.retryOptions.maxRetries + 1; for (let i = 1; i <= totalNumberOfAttempts; i++) { import_log.logger.verbose( "[%s] Attempt number for '%s': %d.", updatedConfig.connectionId, updatedConfig.operationType, i ); try { result = await updatedConfig.operation(); success = true; import_log.logger.verbose( "[%s] Success for '%s', after attempt number: %d.", updatedConfig.connectionId, updatedConfig.operationType, i ); if (result && !isDelivery(result)) { import_log.logger.verbose( "[%s] Success result for '%s': %O", updatedConfig.connectionId, updatedConfig.operationType, result ); } break; } catch (_err) { const err = (0, import_errors.translate)(_err); if (!err.retryable && err.name === "ServiceCommunicationError" && updatedConfig.connectionHost) { const isConnected = await (0, import_checkNetworkConnection.checkNetworkConnection)(updatedConfig.connectionHost); if (!isConnected) { err.name = "ConnectionLostError"; err.retryable = true; } } import_log.logger.verbose( "[%s] Error occurred for '%s' in attempt number %d: %O", updatedConfig.connectionId, updatedConfig.operationType, i, err ); errors.push(err); if (errors[errors?.length - 1].retryable && totalNumberOfAttempts > i) { const targetDelayInMs = calculateDelay( i, updatedConfig.retryOptions.retryDelayInMs, updatedConfig.retryOptions.maxRetryDelayInMs, updatedConfig.retryOptions.mode ); import_log.logger.verbose( "[%s] Sleeping for %d milliseconds for '%s'.", updatedConfig.connectionId, targetDelayInMs, updatedConfig.operationType ); await (0, import_core_util.delay)(targetDelayInMs, { abortSignal: updatedConfig.abortSignal, abortErrorMsg: `The retry operation has been cancelled by the user.` }); continue; } else { break; } } } if (success) { return result; } else { if (errors.length === 1) { throw errors[0]; } throw new AggregateError(errors); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RetryMode, RetryOperationType, retry }); //# sourceMappingURL=retry.js.map