Azure Durable Functions #3 – Patterns : Fan In Fan Out


Fan In Fan out is one of the main usages of Azure Durable Functions

Fan-out/fan-in refers to the pattern of executing multiple functions in parallel, and then waiting for all to finish. Often some aggregation work is done on results returned from the functions.


Let’s see how to achieve this pattern using Azure Durable Functions.

If this is the first time you creating a durable function please follow my post Here, it will have the steps on how to create a durable function and activity functions.

Problem to solve:
You have to generate a invoice for a customer, which should include around 20 orders. So First you need to calculate the order amounts for each order then generate the complete invoice.

let’s see how to solve this using Azure durable functions Fan In Fan Out Patten

Step 1: Add two Activity Functions for orderCalculation & InvoiceGenerations


 public  class OrderCalculationActivity
    {
        [FunctionName("OrderCalculationActivity")]
        public static double CalCulateOrderAmount([ActivityTrigger] string OrderId, ILogger log)
        {
            log.LogInformation($"Order calculation for {OrderId}.");
            return new Random().NextDouble();
        }
    }



  public class InvoiceGenerationActivity
    {
        [FunctionName("InvoiceGenerationActivity")]
        public static bool CalCulateOrderAmount([ActivityTrigger] List<double> orderAmounts, ILogger log)
        {
            log.LogInformation($"Invoice Generated with amount {orderAmounts.Sum()}.");
            return true;
        }
    }

Those are two activities which will be called by the orchestrator. As There is around 20 orders “orderCalculation “ activity will be called for all the orders parallelly. Then after all order calculations completed then need to send the list of order amounts to the “InvoiceGenerations” activity.

Step 2: Add code in the Orchestrator to call order calculation parallelly.


 var orders = context.GetInput<List<string>>();
            var provisioningTasks = new List<Task<double>>();
            for (int i = 0; i < orders.Count; i++)
            {
                var provisionTask = context.CallActivityAsync<double>("OrderCalculationActivity",
                    orders[i]);
                provisioningTasks.Add(provisionTask);
            }

Step 3: Add code in the Orchestrator to call collect the results from all the activities called and pass the result to invoice generation.


 var orderAmounts = await Task.WhenAll(provisioningTasks);

            var invoice =await context.CallActivityAsync<string>("InvoiceGenerationActivity",
                  orderAmounts);

final code of orchestrator will look as follows


using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;

namespace FanInFanOut
{
    public static class Orchestrator
    {
        [FunctionName("Orchestrator")]
        public static async Task<string> RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
            var orders = context.GetInput<List<string>>();
            var provisioningTasks = new List<Task<double>>();
            for (int i = 0; i < orders.Count; i++)
            {
                var provisionTask = context.CallActivityAsync<double>("OrderCalculationActivity",
                    orders[i]);
                provisioningTasks.Add(provisionTask);
            }

            var orderAmounts = await Task.WhenAll(provisioningTasks);

            var invoice =await context.CallActivityAsync<string>("InvoiceGenerationActivity",
                  orderAmounts);

            return invoice;
        }

    }
}

Step 4: Call orchestrator from the starter.


using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Linq;

namespace FanInFanOut
{
    public static class Starter
    {
        [FunctionName("Starter")]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
            [OrchestrationClient]DurableOrchestrationClient starter,
            ILogger log)
        {
            var orderIds = Enumerable.Range(0, 10);
            // Function input comes from the request content.
            string instanceId = await starter.StartNewAsync("Orchestrator", orderIds.ToList());

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}
Following above steps you can see how to implement fan in fan out pattern in Durable Functions.

You Can download the sample code from here

Happy Coding !!!

Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Awesome blog. I enjoyed reading your articles. This is truly a great read for me. Keep up the good work!


    data analytics course

    data science course

    business analytics course

    ReplyDelete
  3. Very nice blog post. Thanks for sharing such helpful article. Keep posting in future also.

    Web Development Company in Bangalore
    Website Development Company in Bangalore

    ReplyDelete
  4. Brilliant article keep up the good work

    ReplyDelete
  5. I just came across your blog post and must say that it’s a great piece of information that you have shared. Visit for more info social media marketing agency in navi mumbai

    ReplyDelete

Post a Comment

Popular posts from this blog

Responsive Web Design

Contract First Development in WCF 4.5

Affine Cipher in C#