Search code examples
azureazure-functionsazure-eventhubazure-functions-runtime

How to identify the azure function execution is a retry?


    [FunctionName("Function1")]
    [ExponentialBackoffRetry(-1, "00:00:03", "00:00:30")]      
    public static async Task Run([EventHubTrigger("test", Connection = "EventHubConnection", 
        ConsumerGroup = "eventprocessor")] EventData[] events,
        ILogger log)
    { }

The above retry policy will make the "EventHubTrigger" Azure function to retry on the occurrence of unhandled exception. If that is the case, how to identify the current execution of the function is a "retry" execution or "normal" i.e., next batch execution?


Solution

  • I tried below code to identify Azure Function retry logic with ExponentialBackoffRetry method and get the current context:-

    My Function1.cs:-

    using System;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.EventHubs;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Extensions.Logging;
    
    namespace FunctionApp6
    {
        public static class Function1
        {
            [Function("Function1")]
            [ExponentialBackoffRetry(5, "00:00:10", "00:10:00")]
            public static async Task Run([EventHubTrigger("siliconeventhub", Connection = "EventHubConnection")] EventData[] events, RetryContext retryContext, ILogger log)
            {
                if (retryContext != null && retryContext.RetryCount > 0)
                {
                    log.LogInformation($"Retry #{retryContext.RetryCount}");
                }
                else
                {
                    log.LogInformation("Normal execution");
                }
    
                foreach (EventData eventData in events)
                {
                    try
                    {
                        byte[] bytes = eventData.Body.ToArray();
                        string messageBody = Encoding.UTF8.GetString(bytes);
                        log.LogInformation($"Eventhub got a message: {messageBody}");
                    }
                    catch (Exception e)
                    {
                        log.LogError($"Error processing message: {e.Message}");
                        throw;
                    }
                }
            }
        }
    }
    

    Alternative code with fully qualified extensions:-

    using System;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.EventHubs;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Extensions.Logging;
    
    namespace FunctionApp6
    {
        public static class Function1
        {
            [Function("Function1")]
            [Microsoft.Azure.Functions.Worker.ExponentialBackoffRetry(5, "00:00:10", "00:10:00")]
            public static async Task Run([Microsoft.Azure.Functions.Worker.EventHubTrigger("siliconeventhub", Connection = "EventHubConnection")] EventData[] events, RetryContext retryContext, ILogger log)
            {
                if (retryContext != null && retryContext.RetryCount > 0)
                {
                    log.LogInformation($"Retry #{retryContext.RetryCount}");
                }
                else
                {
                    log.LogInformation("Normal execution");
                }
    
                foreach (EventData eventData in events)
                {
                    try
                    {
                        byte[] bytes = eventData.Body.ToArray();
                        string messageBody = Encoding.UTF8.GetString(bytes);
                        log.LogInformation($"C# Event Hub got a  message: {messageBody}");
                    }
                    catch (Exception e)
                    {
                        log.LogError($"Error processing message: {e.Message}");
                        throw;
                    }
                }
            }
        }
    }
    
    

    Here, If retry context is less than zero or NULL than it is considered as a normal execution and greater than that is considered as a retry execution.

    Output:-

    enter image description here