According to official documents of the Azure Durable Functions, the fan-out/fan-in use case of it is shown in the example (from same site)
[FunctionName("FanOutFanIn")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
var parallelTasks = new List<Task<int>>();
// Get a list of N work items to process in parallel.
object[] workBatch = await context.CallActivityAsync<object[]>("F1", null);
for (int i = 0; i < workBatch.Length; i++)
{
Task<int> task = context.CallActivityAsync<int>("F2", workBatch[i]);
parallelTasks.Add(task);
}
await Task.WhenAll(parallelTasks);
// Aggregate all N outputs and send the result to F3.
int sum = parallelTasks.Sum(t => t.Result);
await context.CallActivityAsync("F3", sum);
}
Functionally I can do the same thing with:
[FunctionName("FanOutFanIn")]
public static async Task Run(HttpTrigger... )
{
var parallelTasks = new List<Task<int>>();
// Get a list of N work items to process in parallel.
object[] workBatch = await F1(null);
for (int i = 0; i < workBatch.Length; i++)
{
Task<int> task = F2(workBatch[i]);
parallelTasks.Add(task);
}
// custom error handling
try {
await Task.WhenAll(parallelTasks);
} catch (Exception e){
return new BadRequestObjectResult(e.ToString());
}
// Aggregate all N outputs and send the result to F3.
int sum = parallelTasks.Sum(t => t.Result);
bool success = await F3(sum);
return success ? new OkObjectResult("SUCCESS") : new BadRequestObjectResult("ERROR");
}
public static async Task<object[]> F1(...){ ... }
What I want to ask is: What is the advantages of using Azure Durable Functions when you can implement it with not too much trouble with simple async
/await
s?
Do people still prefer to use it while (comparing with using just async
/await
s) it has disadvantages like: replaying of orchestrator fucntion is out of your control, orchestrator functions must use only deterministic stuff - plus the documents don't say how deterministic should it be (1)
I'm not implying there are few or no advantages, I just didn't find such a list on the interwebs.
Many people say the problem Durable Functions solve is the one about fanning in from multiple functions, but I think Durable Functions don't solve that, Task.WhenAll
does, and Durable Functions just use it.
Note (1): I mean the level of deterministication F1
must be to be called in an orchestration function. Could it throw an Exception
? Could it return a list of 5 objects sometimes and a list of 500 objects some other time? They even recommend you not use DateTime.Now
which return the same type of object everytime. If I need the exact same thing everytime I would have defined a const
.