Reputation: 20169
I have a simple Durable Function where my goal is to perform some background work (in this case spin up an Azure Database).
I've got the following code which is working, however I'm wondering what the purpose of need the ActivityTrigger function.
If I don't include it and attempt do work in CreateDB
itself, the Durable Function never correctly completes and remains Running.
public static class CreateDBFn
{
private const string CreateDBConstant = "CreateDB";
private const string CreateDBTaskConstant = CreateDBConstant + "Task";
[FunctionName(CreateDBConstant + "Start")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = CreateDBConstant + "/{Name}")] HttpRequestMessage req,
[OrchestrationClient] DurableOrchestrationClientBase starter,
string Name,
ILogger log)
{
string instanceId = await starter.StartNewAsync(CreateDBConstant, Name);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
var res = starter.CreateCheckStatusResponse(req, instanceId);
res.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(10));
return res;
}
[FunctionName(CreateDBConstant)]
public static async Task<bool> CreateDB([OrchestrationTrigger] DurableOrchestrationContextBase context)
{
var Name = context.GetInput<string>();
// I'd like to just do work here
await Task.Delay(30000);
// Why is it required to call out to an Activity?
var success = await context.CallActivityAsync<bool>(CreateDBTaskConstant, Name);
return true;
}
[FunctionName(CreateDBTaskConstant)]
public static async Task<bool> CreateDBTask([ActivityTrigger] string Name)
{
// preform work
await Task.Delay(30000);
return true;
}
}
Upvotes: 1
Views: 1952
Reputation: 260
It is discouraged to start async operations in orchestrator code, the only exception being code started by the durable orchestration context, for instance CallActivityAsync()
. This is due to the checkpoint-replay behaviour of orchestrator functions.
Relevant excerpts from the documentation
Orchestrator code must never initiate any async operation except by using the DurableOrchestrationContext API. For example, no Task.Run, Task.Delay or HttpClient.SendAsync. The Durable Task Framework executes orchestrator code on a single thread and cannot interact with any other threads that could be scheduled by other async APIs.
Tasks that can be safely awaited in orchestrator functions are occasionally referred to as durable tasks. These are tasks that are created and managed by the Durable Task Framework. Examples are the tasks returned by CallActivityAsync, WaitForExternalEvent, and CreateTimer.
Upvotes: 2