Azure Durable
Funkiness
@stuartleeks
Web and Cloud geek @ Microsoft
The Evolution of
Code
C# Edition
Sync -> Async -> Parallel -> Distributed
Synchronous
void DemoSync()
{
try // try/catch and using work nicely
{
DoStuff();
DoMoreStuff();
DoEvenMoreStuff();
}
catch (Exception ex)
{
// Handle exception
}
}
Asynchronous
async Task<string[]> DemoAsync()
{
try // try/catch and using work nicely
{
var x = await DoStuffAsync();
var y = await DoMoreStuffAsync();
var z = await DoEvenMoreStuffAsync();
return new[] { x, y, z };
}
catch (Exception ex)
{
// Handle exception
}
}
Asynchronous
async Task<string[]> DemoAsync()
{
try // try/catch and using work nicely
{
var x = await DoStuffAsync();
var y = await DoMoreStuffAsync();
var z = await DoEvenMoreStuffAsync();
return new[] { x, y, z };
}
catch (Exception ex)
{
// Handle exception
}
}
Asynchronous
async Task<string[]> Demo2Async()
{
try // try/catch and using work nicely
{
var taskx = DoStuffAsync();
var x = await taskx;
var y = await DoMoreStuffAsync();
var z = await DoEvenMoreStuffAsync();
return new[] { x, y, z };
}
catch (Exception ex)
{
// Handle exception
}
}
Parallel
async Task<string> Demo1Parallel()
{
try // try/catch and using work nicely
{
var task1 = DoStuffAsync();
var task2 = DoMoreStuffAsync();
await task1;
await task2;
return await DoStuffAfterOtherStuffAsync(task1.Result, task2.Result);
}
catch (Exception ex)
{
// Handle exception
}
}
Parallel
async Task<string> DemoParallel()
{
try // try/catch and using work nicely
{
var task1 = DoStuffAsync();
var task2 = DoMoreStuffAsync();
await Task.WhenAll(task1, task2);
return await DoStuffAfterOtherStuffAsync(task1.Result, task2.Result);
}
catch (Exception ex)
{
// Handle exception
}
}
Sync -> Async -> Parallel
Azure Durable Functions
Sync -> Async -> Parallel -> Distributed
Distributed - Chaining
async Task<string[]> Run1(DurableOrchestrationContext ctx)
{
try // try/catch and using work nicely
{
var x = await ctx.CallActivityAsync<string>("DoStuffAsync");
var y = await ctx.CallActivityAsync<string>("DoMoreStuffAsync");
var z = await ctx.CallActivityAsync<string>("DoEvenMoreStuffAsync");
return new[] { x, y, z };
}
catch (Exception)
{
// Handle exception
}
}
Distributed – Fan-out/Fan-in
public static async Task<string> Run2(DurableOrchestrationContext ctx)
{
try // try/catch and using work nicely
{
var task1 = ctx.CallActivityAsync<string>("DoStuffASync");
var task2 = ctx.CallActivityAsync<string>("DoMoreStuffASync");
await Task.WhenAll(task1, task2);
return await ctx.CallActivityAsync<string>("DoStuffAfterOtherStuffAsync", task1.Result, task2.Result);
}
catch (Exception)
{
// Handle exception
}
}
Durable Functions - Patterns
Distributed – Trigger function
[FunctionName("Start")]
public static async Task<HttpResponseMessage> Start(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage request,
[OrchestrationClient] DurableOrchestrationClient starter)
{
var instanceId = await starter.StartNewAsync("WaitForApproval");
return starter.CreateCheckStatusResponse(request, instanceId);
}
Distributed – Timers and External Events
[FunctionName(“WaitForApproval")]
public static async Task<string> WaitForApproval(DurableOrchestrationContext ctx)
{
var approvedTask = ctx.WaitForExternalEvent<string>("Approved");
var cts = new CancellationTokenSource();
var timeoutTask = context.CreateTimer(context.CurrentUtcDateTime.AddMinutes(5), cts.Token);
var winningTask = await Task.WhenAny(approvedTask, timeoutTask);
if (winningTask == timeoutTask)
await ctx.CallActivityAsync<string>(“Escalate");
else
await ctx.CallActivityAsync<string>(“Success");
}
Distributed – Timers and External Events
[FunctionName(“Approve")]
public static async Task<HttpResponseMessage> Approve(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage request,
[OrchestrationClient] DurableOrchestrationClient starter)
{
var instanceId = request.RequestUri.ParseQueryString()["instanceId"];
return starter.RaiseEventAsync(instanceId, "Approved", "Stuart Leeks");
}
Durable Functions - Patterns
Durable Functions
http://aka.ms/durablefunctions
The Evolution of
Code
C# Edition
With Azure Functions
Durable Functions
http://aka.ms/durablefunctions

Azure Durable Funkiness - .NET Oxford June 2018

  • 1.
  • 2.
  • 3.
    Sync -> Async-> Parallel -> Distributed
  • 4.
    Synchronous void DemoSync() { try //try/catch and using work nicely { DoStuff(); DoMoreStuff(); DoEvenMoreStuff(); } catch (Exception ex) { // Handle exception } }
  • 5.
    Asynchronous async Task<string[]> DemoAsync() { try// try/catch and using work nicely { var x = await DoStuffAsync(); var y = await DoMoreStuffAsync(); var z = await DoEvenMoreStuffAsync(); return new[] { x, y, z }; } catch (Exception ex) { // Handle exception } }
  • 6.
    Asynchronous async Task<string[]> DemoAsync() { try// try/catch and using work nicely { var x = await DoStuffAsync(); var y = await DoMoreStuffAsync(); var z = await DoEvenMoreStuffAsync(); return new[] { x, y, z }; } catch (Exception ex) { // Handle exception } }
  • 7.
    Asynchronous async Task<string[]> Demo2Async() { try// try/catch and using work nicely { var taskx = DoStuffAsync(); var x = await taskx; var y = await DoMoreStuffAsync(); var z = await DoEvenMoreStuffAsync(); return new[] { x, y, z }; } catch (Exception ex) { // Handle exception } }
  • 8.
    Parallel async Task<string> Demo1Parallel() { try// try/catch and using work nicely { var task1 = DoStuffAsync(); var task2 = DoMoreStuffAsync(); await task1; await task2; return await DoStuffAfterOtherStuffAsync(task1.Result, task2.Result); } catch (Exception ex) { // Handle exception } }
  • 9.
    Parallel async Task<string> DemoParallel() { try// try/catch and using work nicely { var task1 = DoStuffAsync(); var task2 = DoMoreStuffAsync(); await Task.WhenAll(task1, task2); return await DoStuffAfterOtherStuffAsync(task1.Result, task2.Result); } catch (Exception ex) { // Handle exception } }
  • 10.
    Sync -> Async-> Parallel
  • 11.
  • 12.
    Sync -> Async-> Parallel -> Distributed
  • 13.
    Distributed - Chaining asyncTask<string[]> Run1(DurableOrchestrationContext ctx) { try // try/catch and using work nicely { var x = await ctx.CallActivityAsync<string>("DoStuffAsync"); var y = await ctx.CallActivityAsync<string>("DoMoreStuffAsync"); var z = await ctx.CallActivityAsync<string>("DoEvenMoreStuffAsync"); return new[] { x, y, z }; } catch (Exception) { // Handle exception } }
  • 14.
    Distributed – Fan-out/Fan-in publicstatic async Task<string> Run2(DurableOrchestrationContext ctx) { try // try/catch and using work nicely { var task1 = ctx.CallActivityAsync<string>("DoStuffASync"); var task2 = ctx.CallActivityAsync<string>("DoMoreStuffASync"); await Task.WhenAll(task1, task2); return await ctx.CallActivityAsync<string>("DoStuffAfterOtherStuffAsync", task1.Result, task2.Result); } catch (Exception) { // Handle exception } }
  • 15.
  • 16.
    Distributed – Triggerfunction [FunctionName("Start")] public static async Task<HttpResponseMessage> Start( [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage request, [OrchestrationClient] DurableOrchestrationClient starter) { var instanceId = await starter.StartNewAsync("WaitForApproval"); return starter.CreateCheckStatusResponse(request, instanceId); }
  • 17.
    Distributed – Timersand External Events [FunctionName(“WaitForApproval")] public static async Task<string> WaitForApproval(DurableOrchestrationContext ctx) { var approvedTask = ctx.WaitForExternalEvent<string>("Approved"); var cts = new CancellationTokenSource(); var timeoutTask = context.CreateTimer(context.CurrentUtcDateTime.AddMinutes(5), cts.Token); var winningTask = await Task.WhenAny(approvedTask, timeoutTask); if (winningTask == timeoutTask) await ctx.CallActivityAsync<string>(“Escalate"); else await ctx.CallActivityAsync<string>(“Success"); }
  • 18.
    Distributed – Timersand External Events [FunctionName(“Approve")] public static async Task<HttpResponseMessage> Approve( [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage request, [OrchestrationClient] DurableOrchestrationClient starter) { var instanceId = request.RequestUri.ParseQueryString()["instanceId"]; return starter.RaiseEventAsync(instanceId, "Approved", "Stuart Leeks"); }
  • 19.
  • 20.
  • 21.
    The Evolution of Code C#Edition With Azure Functions Durable Functions http://aka.ms/durablefunctions