@azure/core-amqp
Version:
Common library for amqp based azure sdks like @azure/event-hubs.
176 lines (175 loc) • 6.64 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 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