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); } } }
You Can download the sample code from here
Happy Coding !!!
This comment has been removed by a blog administrator.
ReplyDeleteAwesome blog. I enjoyed reading your articles. This is truly a great read for me. Keep up the good work!
ReplyDeletedata analytics course
data science course
business analytics course
Very nice blog post. Thanks for sharing such helpful article. Keep posting in future also.
ReplyDeleteWeb Development Company in Bangalore
Website Development Company in Bangalore
Brilliant article keep up the good work
ReplyDeleteI 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