Microsoft have recently released retry policies for Azure Functions (preview), which can be applied using the FixedDelayRetry and ExponentialBackoffRetry attributes. Do these retry policies hook into the Azure Functions runtime and operate at a level below the function invocations, or are they effectively the same as an await Task.Delay in user-code? Specifically, would the retry delays of these policies count towards the function execution time, and hence be billed and cause timeouts if they exceed the 10-minute maximum duration on consumption plan?
I can only find the following relevant method in the source code (simplified version below), which enforces retry delays using an await Task.Delay, but I might be missing something.
namespace Microsoft.Azure.WebJobs.Host.Executors
{
internal static class FunctionExecutorExtensions
{
public static async Task<IDelayedException> TryExecuteAsync(this IFunctionExecutor executor, Func<IFunctionInstance> instanceFactory, ILoggerFactory loggerFactory, CancellationToken cancellationToken)
{
var attempt = 0;
while (true)
{
var functionInstance = instanceFactory.Invoke();
var functionException = await executor.TryExecuteAsync(functionInstance, cancellationToken);
if (functionException == null)
return null; // function invocation succeeded
if (functionInstance.FunctionDescriptor.RetryStrategy == null)
return functionException; // retry is not configured
var retryStrategy = functionInstance.FunctionDescriptor.RetryStrategy;
if (retryStrategy.MaxRetryCount != -1 && ++attempt > retryStrategy.MaxRetryCount)
return functionException; // retry count exceeded
TimeSpan nextDelay = retryStrategy.GetNextDelay(retryContext);
await Task.Delay(nextDelay);
}
}
}
}
There are many shortcomings in other aspects of these retry policies, so unless they offer some advantage through their integration with the functions runtime, I'd prefer to stick with a mature reusable library such as Polly.
- The retry policies cannot be customized.
ExponentialBackoffRetryuses a hardcoded factor of 2 that cannot be changed.FixedDelayRetrydoes not support random jitter, andExponentialBackoffRetryhas a hardcoded random jitter of ±20%. - Retry failures get logged as errors, needlessly cluttering the error logs. It doesn't seem possible to disable these retry errors without losing all other function errors too.
- There is no way of getting the retry count.
RetryContextstill gives a binding error on the latest non-beta packages. - Technical documentation is sparse, with the above details needing to be inferred from the source code.