Created
September 16, 2020 21:13
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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