Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions sdk/servicebus/service-bus/src/receivers/receiverCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ import {
import { DispositionStatusOptions } from "../core/managementClient";
import { ConnectionContext } from "../connectionContext";
import {
Constants,
ErrorNameConditionMapper,
delay,
retry,
RetryConfig,
RetryMode,
RetryOperationType,
RetryOptions,
} from "@azure/core-amqp";
Expand Down Expand Up @@ -279,6 +282,28 @@ export interface RetryForeverArgs<T> {
logPrefix: string;
}

/**
* Calculates delay between retries, in milliseconds.
* @internal

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to tag it as internal if it is not exported.

*/
function calculateDelay(
attemptCount: number,
retryDelayInMs: number,
maxRetryDelayInMs: number,
mode: RetryMode
): number {
if (mode === RetryMode.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;
}

/**
* Retry infinitely until success, reporting in between retry attempts.
*
Expand All @@ -293,6 +318,22 @@ export async function retryForever<T>(
retryFn: typeof retry = retry
): Promise<T> {
let numRetryCycles = 0;
const config = args.retryConfig;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I duplicated the code from core-amqp's retry as they are used internally and not really worth to expose to reuse.

if (!config.retryOptions) {
config.retryOptions = {};
}
if (config.retryOptions.retryDelayInMs == undefined || config.retryOptions.retryDelayInMs < 0) {
config.retryOptions.retryDelayInMs = Constants.defaultDelayBetweenOperationRetriesInMs;
}
if (
config.retryOptions.maxRetryDelayInMs == undefined ||
config.retryOptions.maxRetryDelayInMs < 0
) {
config.retryOptions.maxRetryDelayInMs = Constants.defaultMaxDelayForExponentialRetryInMs;
}
if (config.retryOptions.mode == undefined) {
config.retryOptions.mode = RetryMode.Fixed;
}

// The retries are broken up into cycles, giving the user some control over how often
// we actually attempt to retry.
Expand Down Expand Up @@ -325,6 +366,20 @@ export async function retryForever<T>(
args.retryConfig
);

const delayInMs = calculateDelay(
numRetryCycles,
config.retryOptions.retryDelayInMs,
config.retryOptions.maxRetryDelayInMs,
config.retryOptions.mode
);
logger.verbose(
"[%s] Sleeping for %d milliseconds for '%s'.",
config.connectionId,
delayInMs,
config.operationType
);
await delay<void>(delayInMs, config.abortSignal, "Retry cycle has been cancelled by the user.");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changelog?


continue;
}
}
Expand Down