Skip to content

Instantly share code, notes, and snippets.

@marcduiker
Created September 16, 2020 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcduiker/11df779cda6ff6f793c25d56267ad8d5 to your computer and use it in GitHub Desktop.
Save marcduiker/11df779cda6ff6f793c25d56267ad8d5 to your computer and use it in GitHub Desktop.
Possible solution to retry calls and escalate when the callee does not respond within a certain time.
namespace DurableFunctions.Demo.DotNetCore.RetryCallsWithBackup
{
public class EscalatingCallsOrchestrator
{
[FunctionName(nameof(RunEscalatingCallsOrchestrator))]
public async Task RunEscalatingCallsOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger logger)
{
var escalatingCallsInput = context.GetInput<EscalatingCallsInput>();
var resultCall1 = await context.CallSubOrchestratorAsync<bool>(
nameof(RunRetryCallsOrchestrator),
escalatingCallsInput.PhoneNumbers[0]);
if (!resultCall1)
{
// Call1 has not been received within the wait time. Let's try Call3.
var resultCall2 = await context.CallSubOrchestratorAsync<bool>(
nameof(RunRetryCallsOrchestrator),
escalatingCallsInput.PhoneNumbers[1]);
if (!resultCall2)
{
// Call2 has not been received within the wait time. Let's try Call3.
var resultCall3 = await context.CallSubOrchestratorAsync<bool>(
nameof(RunRetryCallsOrchestrator),
escalatingCallsInput.PhoneNumbers[0]);
}
}
}
[FunctionName(nameof(RunRetryCallsOrchestrator))]
public async Task<bool> RunRetryCallsOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger logger)
{
var input = context.GetInput<RetryCallInput>();
var maxWaitTimeBetweenCalls = TimeSpan.FromMinutes(5/3); // max 5 min wait time, divided by 3 attempts to call
await context.CallActivityAsync("MakeCall", input.PhoneNumber);
// Orchestrator will wait until Call event is received or maxWaitTimeBetweenCalls is passed, defauls to false.
var resultCall = await context.WaitForExternalEvent<bool>("Call", maxWaitTimeBetweenCalls, false);
if (input.RunCount < 2)
{
input.RunCount += 1;
context.ContinueAsNew(input);
}
return resultCall;
}
}
public class EscalatingCallsInput
{
public string[] PhoneNumbers { get; set; }
}
public class RetryCallInput
{
public string PhoneNumber { get; set; }
public int RunCount { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment