Setting up Orchestrations
Starting Orchestrations
Orchestrations with Durable Functions are started by using the StartNewAsync
method on the DurableOrchestrationClient. An instance of DurableOrchestrationClient
can be retrieved by using the OrchestrationClientAttribute
binding. The binding can be paired with exiting function triggers.
[FunctionName("RunOrchestration")]
public static async Task<HttpResponseMessage> RunOrchestration(
[HttpTrigger(AuthorizationLevel.Anonymous, "POST")]HttpRequestMessage req,
[OrchestrationClient] DurableOrchestrationClient orchestrationClient)
{
OrderRequestData data = await req.Content.ReadAsAsync<OrderRequestData>();
string instanceId = await orchestrationClient.StartNewAsync("PlaceOrder", data);
return orchestrationClient.CreateCheckStatusResponse(req, instanceId);
}
Takeaways
StartNewAsync
method ofDurableOrchestrationClient
is used to start a stateful workflow.StartNewAsync
has overloads that accept input that may need to be passed to the orchestration.- The
OrchestrationClient
binding is used to get access to theDurableOrchestrationClient
- The
OrchestrationClient
binding can be used with core Azure Functions triggers.
Read more
- Durable Functions overview
- Bindings for Durable Functions
- Durable Functions NuGet package
- Azure Functions triggers and bindings concepts
Authoring Orchestrator Functions
Orchestrator functions are responsible for managing the stateful workflows in Durable Functions. They take care of checkpointing progress and resuming workflows that are waiting for activities to complete. OrchestrationTriggerAttribute
is used to annotate functions as orchestrator functions.
Orchestration functions support only DurableOrchestrationContext
as a parameter type. DurableOrchestrationContext
has methods that allow you to call activity functions, call sub-orchestrations, get input data for the orchestrator, and a few others.
[FunctionName("PlaceOrder")]
public static async Task<InvoiceData> OrderOrchestration([OrchestrationTrigger] DurableOrchestrationContext context)
{
OrderRequestData orderData = context.GetInput<OrderRequestData>();
//long running operation
InvoiceData invoice = await context.CallActivityAsync<InvoiceData>("ProcessPayment", orderData);
return invoice;
}
Takeaways
OrchestrationTriggerAttribute
marks functions are orchestrator functions.DurableOrchestrationContext
is used to interact with the activity functions the make up the stateful workflow.- Orchestrator functions all run on a single dispatcher thread per host. Therefore, orchestrators should not perform any I/O operations.
- Orchestrator functions can return output values. The output must be JSON-serializable.
- A null value will be saved as the output if an orchestrator function returns
Task
orvoid
.
Read more
Authoring Activity Functions
Activities are composed together in orchestrator functions to create a stateful workflow. Activities are where most of the processing happens for a given orchestration. ActivityTriggerAttribute
is used to annotate functions as orchestration activities.
Activity functions can accept either an instance of DurableActivityContext
or a JSON serializable type as a parameter. The return values are serialized to JSON and persisted to the orchestration history table when the orchestrator function does checkpointing.
[FunctionName("CheckAndReserveInventory")]
public static bool CheckAndReserveInventory([ActivityTrigger] DurableActivityContext context)
{
OrderRequestData orderData = context.GetInput<OrderRequestData>();
// Check inventory system and reserve products
return true;
}
Takeaways
ActivityTriggerAttribute
marks functions as orchestration activities.DurableActivityContext
can be used to access input values for the activities- Activities functions can return output values. The output must be JSON-serializable.
- A null value will be saved as the output if an orchestrator function returns
Task
orvoid
.