Managing Orchestrations

Identifying Instances

When is started by using the StartNewAsync method on the DurableOrchestrationClient, the unique instance ID for that orchestration is returned. If an instance ID isn't provided to the StartNewAsync call, a random ID will be generated.

The instance ID can be stored so that future management operations can be invoked on the respective orchestration.

[FunctionName("RunOrchestration")]
public static async Task RunOrchestration(
    [QueueTrigger("my-orchestration-queue")] string instanceID,
    [OrchestrationClient] DurableOrchestrationClient orchestrationClient,
    TraceWriter log)
{
    string instanceId = await orchestrationClient.StartNewAsync("PlaceOrder", input);
    log.Info($"Started orchestration with ID = '{instanceId}'.");
}

Takeaways

  • StartNewAsync method of DurableOrchestrationClient is used to start a stateful workflow.
  • StartNewAsync returns a unique instance ID for the orchestration invocation.
  • The instance ID can be used to query the status of the orchestration and run other management operations.

Read more

Exposing HTTP Management APIs

When using a HttpTrigger along with Durable Functions, the CreateCheckStatusResponse method from DurableOrchestrationClient enables the creation of an HttpResponseMessage. The response contains links to the various management operations that can be invoked on an orchestration instance. These operations include querying the orchestration status, raising events, and terminating the orchestration.

[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);
}

The HTTP response body will resemble the following JSON payload, which contains the instance ID and management endpoints.

{
    "id": "instanceId",
    "statusQueryGetUri": "http://host/statusUri",
    "sendEventPostUri": "http://host/eventUri",
    "terminatePostUri": "http://host/terminateUri"
}

Takeaways

  • CreateCheckStatusResponse method of DurableOrchestrationClient returns an HttpResponseMessage instance containing management links.
  • The links in the payload are endpoints to the management API operations.
  • CreateCheckStatusResponse requires the unique instance ID.

Read more

Inspecting the status of an orchestration

The status of an orchestration instance can be queried using the GetStatusAsync method from DurableOrchestrationClient. The only required parameter is the instance ID of the orchestration to be inspected. The status query will include information like the orchestrator function name, creation time, and also running status.

Optionally, GetStatusAsync accepts a showHistory boolean parameter that will include the execution history of the orchestration. Another optional parameter, showHistoryOutput, can be provided to include the outputs of the activity functions in the status query.

[FunctionName("CheckOrchestration")]
public static async Task CheckOrchestration(
    [QueueTrigger("my-orchestration-status-queue")] string instanceID,
    [OrchestrationClient] DurableOrchestrationClient orchestrationClient)
{
    DurableOrchestrationStatus status = await orchestrationClient.GetStatusAsync(instanceID, showHistory: true);

    if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed) {
        //do something with this completed orchestration
    }
}

Takeaways

  • GetStatusAsync method of DurableOrchestrationClient can be used to get status information for a given orchestration.
  • Alternatively, the status endpoint returned from CreateCheckStatusResponse can be used.
  • The execution history and results can be included in the response if showHistory and showHistoryOutput are set to true.
  • GetStatusAsync returns an instance of DurableOrchestrationStatus that contains all the status information.

Read more

Sending event notifications

Orchestrations can be sent event notifications by using the RaiseEventAsync method of DurableOrchestrationClient. The method must be provided with the instance ID, an event name, and the associated event data.

[FunctionName("NotifyEvent")]
public static async Task NotifyEvent(
    [QueueTrigger("event-queue")] NotificationInfo notification,
    [OrchestrationClient] DurableOrchestrationClient orchestrationClient)
{
    await orchestrationClient.RaiseEventAsync(notification.instanceID, notification.EventName, notification.EventData);
}

Orchestrations waiting for event notifications can use the WaitForExternalEvent method on their DurableOrchestrationContext instance. The method takes the event type as a generic type parameter as well as the event name as a function parameter.

[FunctionName("PlaceOrder")]
public static async Task<InvoiceData> OrderOrchestration([OrchestrationTrigger] DurableOrchestrationContext context)
{
    OrderRequestData orderData = context.GetInput<OrderRequestData>();

    bool inventoryReserved = await context.CallActivityAsync<bool>("CheckAndReserveInventory", orderData);

    if (!inventoryReserved) {
        await context.WaitForExternalEvent<object>("Proceed");
        await context.CallActivityAsync<bool>("CheckAndReserveInventory", orderData);
    }

    InvoiceData invoice = await context.CallActivityAsync<InvoiceData>("ProcessPayment", orderData);
    return invoice;
}

Takeaways

  • RaiseEventAsync method of DurableOrchestrationClient can be used to send event notifications to orchestrations.
  • WaitForExternalEvent on DurableOrchestrationContext can be used to pause execution until a notification is received.
  • Alternatively, the notification endpoint returned from CreateCheckStatusResponse can be used.

Read more

Terminating a running orchestration instance

An orchestration instance can be terminated using the TerminateAsync method on DurableOrchestrationClient. The instance ID of the orchestration and a reason string must be passed to TerminateAsync.

[FunctionName("TerminateOchestration")]
public static async Task TerminateOchestration(
    [QueueTrigger("orchestration-termination-queue")] string instanceID,
    [OrchestrationClient] DurableOrchestrationClient orchestrationClient)
{
    string terminationReason = "Tired of waiting on this one";
    await orchestrationClient.TerminateAsync(instanceID, terminationReason);
}

Takeaways

  • TerminateAsync method of DurableOrchestrationClient can be used to terminate a running orchestration.
  • Alternatively, the termination endpoint returned from CreateCheckStatusResponse can be used.

Read more