Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Logging in orchestrator functions
An orchestrator function creates checkpoints as each of its composite activity functions complete. After each call to CallActivityAsync on the DurableOrchestrationContext instance completes, the orchestrator function will automatically replay to rebuild their in-memory state.
To prevent logging statements from duplicating, use the IsReplaying property on the DurableOrchestrationContext.
[FunctionName("PlaceOrder")]
public static async Task<InvoiceData> OrderOrchestration(
[OrchestrationTrigger] DurableOrchestrationContext context,
ILogger log)
{
OrderRequestData orderData = context.GetInput<OrderRequestData>();
if (!context.IsReplaying) log.LogInformation("About Checking inventory");
await context.CallActivityAsync<bool>("CheckAndReserveInventory", orderData);
if (!context.IsReplaying) log.LogInformation("Processing payment");
InvoiceData invoice = await context.CallActivityAsync<InvoiceData>("ProcessPayment", orderData);
return invoice;
}
Takeaways
GetStatusAsyncmethod ofDurableOrchestrationClientcan be used to get status information for a given orchestration.- Alternatively, the status endpoint returned from
CreateCheckStatusResponsecan be used. - The execution history and results can be included in the response if
showHistoryandshowHistoryOutputare set to true. GetStatusAsyncreturns an instance ofDurableOrchestrationStatusthat contains all the status information.
Read more
- HTTP APIs in Durable Functions
- Debugging and Diagnostics of Durable Functions
- Durable Functions repo and samples
Handling activity function exceptions
Unhandled exceptions thrown in activity functions will be rethrown in the calling orchestrator function as a FunctionFailedException. The InnerException property of the FunctionFailedException will contain the original exception from the activity.
[FunctionName("PlaceOrder")]
public static async Task OrderOrchestration(
[OrchestrationTrigger] DurableOrchestrationContext context,
TraceWriter log)
{
try
{
await context.CallActivityAsync<bool>("CheckAndReserveInventory", null);
}
catch (FunctionFailedException ex)
{
log.Error("Inventory check failed", ex);
}
}
[FunctionName("CheckAndReserveInventory")]
public static bool CheckAndReserveInventory([ActivityTrigger] DurableActivityContext context)
{
throw new ArgumentException("Oops...");
}
Takeaways
FunctionFailedExceptionis thrown in the orchestrator if an activity function throws an unhandled exceptionFunctionFailedException'sInnerExceptionproperty will contain the source exception from the activity function.
Read more
- Handling errors in Durable Functions
- Debugging and Diagnostics of Durable Functions
- Durable Functions repo and samples
Calling activity functions with retry
When call activities in your orchestration functions, you may want to apply a retry policy to handle transient errors that may occur. In such cases, the DurableOrchestrationContext provides the CallActivityWithRetryAsync method. The difference between CallActivityAsync and CallActivityWithRetryAsync is that the latter accepts a type of RetryOptions that specifies the retry behavior.
public static async Task OrderOrchestration(
[OrchestrationTrigger] DurableOrchestrationContext context,
ILogger log)
{
RetryOptions retryPolicy = new RetryOptions(
firstRetryInterval: TimeSpan.FromSeconds(3),
maxNumberOfAttempts: 3);
retryPolicy.Handle = (ex) =>
{
TaskFailedException failedEx = ex as TaskFailedException;
return (failedEx.Name != "CheckAndReserveInventory") ? false : true;
};
try
{
await context.CallActivityWithRetryAsync<bool>("CheckAndReserveInventory", retryPolicy, null);
}
catch (FunctionFailedException ex)
{
log.LogError("Inventory check failed", ex);
}
}
Here is an activity function that throws an exception.
[FunctionName("CheckAndReserveInventory")]
public static async Task<bool> CheckAndReserveInventory([ActivityTrigger] DurableActivityContext context)
{
throw new Exception("Ooops...");
}
Takeaways
CallActivityWithRetryAsyncallows orchestrator functions to call activities with retry behavior.- A
RetryOptionsinstance is used to define retry behavior. - A
RetryOptionsinstance can be reused across multiple calls toCallActivityWithRetryAsync. - The
Handleproperty onRetryOptionslets callers define whether retries should proceed or not.