Skip to content

Feature Durable Timers

Akash Kava edited this page May 9, 2021 · 3 revisions

Users can wait on async timer events within the orchestration code.

public class EncodeVideoOrchestration : TaskOrchestration<string, string>
{
    public override async Task<string> RunTask(OrchestrationContext context, string input)
    {
        string encodedUrl = await context.ScheduleTask<string>(typeof (EncodeActivity), input);
        await context.CreateTimer(context.CurrentUtcDateTime.Add(TimeSpan.FromDays(1)), "timer1");
        await context.ScheduleTask<object>(typeof (EmailActivity), input);
                
        return encodedUrl;
    }
}

The line that awaits the CreateTimer task will cause the orchestration to sleep for one day between the encode video and the email activity.

Timers can be used to do periodic work as well as timeouts.

public class BillingOrchestration : TaskOrchestration<string, string>
{
    public override async Task<string> RunTask(OrchestrationContext context, string input)
    {
        for (int i = 0; i < 10; i++)
        {
            await context.CreateTimer(context.CurrentUtcDateTime.Add(TimeSpan.FromDays(1)), "timer1");
            await context.ScheduleTask<object>(typeof (BillingActivity));
        }
        return null;
    }
}

In the snippet above, the billing orchestration will be signaled every day and would invoke some billing activity on waking up.

public class GetQuoteOrchestration : TaskOrchestration<string, string>
{
    public override async Task<string> RunTask(OrchestrationContext context, string input)
    {
        CancellationTokenSource cancellationTokenForTimer = new CancellationTokenSource();
        Task timer = context.CreateTimer(
            context.CurrentUtcDateTime.Add(TimeSpan.FromSeconds(5)), "timer1", cancellationTokenForTimer.Token);
        Task getQuote = context.ScheduleTask<object>(typeof(GetQuote));
        Task winner = await Task.WhenAny(timer, getQuote);
        if (timer.IsCompleted)
        {
            // request timed out, do some compensating action
        }
        else
        {
            // without this, timer will still block
            // orchestration completion
            cancellationTokenForTimer.Cancel();

            // use getQuote task result
        }
        return null;
    }
}

In this snippet, we schedule the GetQuote activity and also create a timer to fire in 5 seconds. If the timer fires before the activity returns then we run some compensation otherwise we use the returned quote.