Last active
November 27, 2020 13:52
-
-
Save alanta/4b8cf669430fa6ee8e876ea016ba903e to your computer and use it in GitHub Desktop.
Singleton eternal function with watchdog timer
This file contains 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
using Microsoft.Azure.WebJobs; | |
using Microsoft.Azure.WebJobs.Extensions.DurableTask; | |
using Microsoft.Extensions.Logging; | |
using System; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace DurableFunctionsPatterns | |
{ | |
public class EternalFunctionWithWatchdogTimer | |
{ | |
private const string FunctionName = "EternalFunctionWithWatchdogTimer"; | |
private const string UniqueInstanceId = "MyBackgroundProcess"; | |
private const string EveryMinute = "0 */1 * * * *"; | |
private readonly ILogger<Orchestrator> _logger; | |
public EternalFunctionWithWatchdogTimer(ILogger<Orchestrator> logger) | |
{ | |
_logger = logger; | |
} | |
[FunctionName(FunctionName+"_WatchdogTimer")] | |
public async Task TimerStart( | |
[TimerTrigger(EveryMinute, RunOnStartup = true)] | |
TimerInfo timer, | |
[DurableClient] IDurableOrchestrationClient starter) | |
{ | |
await EnsureRunning(starter); | |
} | |
private async Task EnsureRunning(IDurableOrchestrationClient starter) | |
{ | |
// Check if an instance with the specified ID already exists or an existing one stopped running(completed/failed/terminated). | |
var existingInstance = await starter.GetStatusAsync(UniqueInstanceId); | |
if (existingInstance == null | |
|| existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Completed | |
|| existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Failed | |
|| existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Terminated) | |
{ | |
var startedInstance = await starter.StartNewAsync(FunctionName, instanceId: UniqueInstanceId); | |
_logger.LogInformation("Started orchestration {instance}'.", UniqueInstanceId); | |
} | |
else | |
{ | |
_logger.LogDebug($"Orchestration {UniqueInstanceId} is running."); | |
} | |
} | |
private Random random = new Random(DateTime.UtcNow.Millisecond); | |
[FunctionName(FunctionName)] | |
public async Task RunOrchestrator( | |
[OrchestrationTrigger] IDurableOrchestrationContext context) | |
{ | |
_logger.LogInformation($"Do stuff {context.InstanceId}"); | |
if (random.Next(10) > 7) | |
{ | |
throw new InvalidOperationException("Random exception that terminates the orchestrator"); | |
} | |
// sleep for a while | |
DateTime nextCleanup = context.CurrentUtcDateTime.AddSeconds(20); | |
await context.CreateTimer(nextCleanup, CancellationToken.None); | |
_logger.LogInformation($"Wake up {context.InstanceId}"); | |
context.ContinueAsNew(null); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment