在 Azure 中管理 Durable Functions 中的執行個體

Durable Functions 中的協調流程是長時間執行的具狀態函式,可使用內建的管理 API 啟動、查詢、暫止、繼續和終止。 其他數個執行個體管理 API 也會由 Durable Functions 的協調流程用戶端繫結來公開,例如將外來事件傳送至執行個體、清除執行個體歷程記錄等。本文將詳細說明所有支援的執行個體管理作業。

啟動執行個體

協調流程用戶端繫結上的 start-new (或 schedule-new) 方法會啟動新的協調流程。 在內部,個方法會透過 Durable Functions 儲存體提供者寫入訊息,然後傳回。 此訊息會以非同步方式會觸發具有指定名稱的協調流程函式啟動。

啟動新協調流程執行個體的參數如下所示:

  • Name:要排程的協調器函式的名稱。
  • Input:應該當作輸入傳給協調器函式的任何 JSON 可序列化資料。
  • InstanceId:(選擇性) 執行個體的唯一識別碼。 如果您未指定此參數,此方法會使用隨機的識別碼。

提示

請儘可能使用隨機的識別碼作為執行個體識別碼。 在將協調器函式擴充至多個虛擬機器時,隨機的執行個體識別碼有助於確保負載均等分散。 當識別碼一定是來自外部來源,或在您實作單次協調器模式時,才是使用非隨機執行個體識別碼的適當時機。

下列程式碼是啟動新協調流程執行個體的函式範例:

[FunctionName("HelloWorldQueueTrigger")]
public static async Task Run(
    [QueueTrigger("start-queue")] string input,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    string instanceId = await starter.StartNewAsync("HelloWorld", input);
    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

Azure Functions Core Tools

您也可以使用 Core Tools 中的 func durable start-new 命令直接啟動執行個體,其會採用下列參數:

  • function-name (必要):要啟動的函式名稱。
  • input (選用):內嵌或透過 JSON 檔案輸入至函式。 若透過檔案,請在檔案路徑新增 @ 作為前置詞,例如 @path/to/file.json
  • id (選用):協調流程執行個體的識別碼。 如果您未指定此參數,此命令會使用隨機識別碼。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設為 AzureWebJobsStorage。
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設為 DurableFunctionsHub。 您也可以透過使用 durableTask:HubName,在 host.json 中設定此項目。

注意

Core Tools 命令假設您會從函數應用程式的根目錄中執行命令。 如果明確提供 connection-string-settingtask-hub-name 參數,您就可以從任何目錄執行命令。 雖然可以在未執行函數應用程式主機的情況下執行這些命令,但您可能會發現除非主機正在執行,否則無法觀察到某些效果。 例如,start-new 命令會將啟動訊息佇列加入目標工作中樞內,但協調流程並不會實際執行,除非有可以處理訊息的函數應用程式主機處理序在執行。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

下列命令會啟動名為 HelloWorld 的函式,並在該函式中傳入檔案 counter-data.json 的內容:

func durable start-new --function-name HelloWorld --input @counter-data.json --task-hub-name TestTaskHub

查詢執行個體

啟動新的協調流程執行個體之後,您很可能必須查詢其執行階段狀態,以了解其狀態為執行中、已完成或已失敗。

協調流程用戶端繫結上的 get-status 方法會查詢協調流程執行個體的狀態。

它會以 instanceId (必要)、showHistory (選用)、showHistoryOutput (選用) 和 showInput (選用) 作為參數。

  • showHistory:如果設為 true,回應會包含執行歷程記錄。
  • showHistoryOutput:如果設為 true,則執行歷程記錄會包含活動輸出。
  • showInput:如果設為 false,回應不會包含函式的輸入。 預設值是 true

此方法會傳回具有下列屬性的物件:

  • Name:協調器函式的名稱。
  • InstanceId:協調流程的執行個體識別碼 (應該與 instanceId 輸入相同)。
  • CreatedTime:協調器函式開始執行的時間。
  • LastUpdatedTime:協調流程前次執行檢查點檢查的時間。
  • Input:函式的 JSON 值輸入。 如果 showInput 為 false,則不會填入這個欄位。
  • CustomStatus:JSON 格式的自訂協調流程狀態。
  • Output:函式的 JSON 值輸出 (如果函式已完成)。 如果協調器函式失敗,此屬性會包含失敗詳細資料。 如果協調器函式暫止或終止,此屬性會包含暫止或終止原因 (如果有的話)。
  • RuntimeStatus:下列其中一個值:
    • 擱置:已排程的執行個體尚未開始執行。
    • Running:執行個體已開始執行。
    • Completed:執行個體已正常完成。
    • ContinuedAsNew:執行個體本身以新的記錄重新啟動。 這個狀態是暫時性狀態。
    • Failed:函式失敗,發生錯誤。
    • Terminated:執行個體已突然停止。
    • Suspended:執行個體暫止,可能會在之後的時間點繼續。
  • 歷程記錄:協調流程的執行記錄。 只有在 showHistory 設為 true 時,才會填入此欄位。

注意

在協調器的所有排程工作都完成「且」傳回之前,協調器不會標示為 Completed。 換句話說,協調器觸達其 return 陳述式並不足以將其標示為 Completed。 這與使用 WhenAny 的情況尤其相關;這些協調器經常在所有排程的工作執行之前 return

此方法會傳回 null (.NET 和 JAVA)、undefined (JavaScript),或 None (Python) (如果執行個體不存在)。

[FunctionName("GetStatus")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("check-status-queue")] string instanceId)
{
    DurableOrchestrationStatus status = await client.GetStatusAsync(instanceId);
    // do something based on the current status.
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

Azure Functions Core Tools

您也可以使用 Core Tools 中的 func durable get-runtime-status 命令,直接取得協調流程執行個體的狀態。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable get-runtime-status 命令採用下列參數:

  • id (必要):協調流程執行個體的識別碼。
  • show-input (選用):如果設為 true,回應會包含函式的輸入。 預設值是 false
  • show-output (選用):如果設為 true,回應會包含函式的輸出。 預設值是 false
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設值為 DurableFunctionsHub。 也可以在 host.json 中使用 durableTask:HubName 來進行設定。

下列命令會針對協調流程執行個體識別碼為 0ab8c55a66644d68a3a8b220b12d209c 的執行個體,擷取其狀態 (包括輸入和輸出)。 它假設您正在從函數應用程式的根目錄執行 func 命令:

func durable get-runtime-status --id 0ab8c55a66644d68a3a8b220b12d209c --show-input true --show-output true

您可以使用 durable get-history 命令擷取協調流程執行個體的歷程記錄。 它需要以下參數:

  • id (必要):協調流程執行個體的識別碼。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設值為 DurableFunctionsHub。 也可以在 host.json 中使用 durableTask:HubName 來進行設定。
func durable get-history --id 0ab8c55a66644d68a3a8b220b12d209c

查詢所有執行個體

您可以使用語言 SDK 中的 API 來查詢工作中樞內所有協調流程執行個體的狀態。 這個 "list-instances" 或 "get-status" API 會傳回物件清單,代表與查詢參數相符的協調流程執行個體。

[FunctionName("GetAllStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var noFilter = new OrchestrationStatusQueryCondition();
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        noFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
    
    // Note: ListInstancesAsync only returns the first page of results.
    // To request additional pages provide the result.ContinuationToken
    // to the OrchestrationStatusQueryCondition's ContinuationToken property.
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

Azure Functions Core Tools

您也可以使用 Core Tools 中的func durable get-instances 命令,直接查詢執行個體。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable get-instances 命令採用下列參數:

  • top (選用):這個命令支援分頁。 此參數會對應至每個要求擷取的執行個體數目。 預設值為 10。
  • continuation-token (選用):用來指出所要擷取執行個體頁面或區段的權杖。 每個 get-instances 執行都會將權杖傳回給下一組執行個體。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設值為 DurableFunctionsHub。 也可以在 host.json 中使用 durableTask:HubName 來進行設定。
func durable get-instances

利用篩選條件查詢執行個體

如果您並不真的需要標準執行個體查詢提供的所有資訊,該怎麼辦? 例如,如果您只想尋找協調流程建立時間或協調流程執行階段狀態,該怎麼辦? 您可以套用篩選縮小查詢範圍。

[FunctionName("QueryStatus")]
public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    // Get the first 100 running or pending instances that were created between 7 and 1 day(s) ago
    var queryFilter = new OrchestrationStatusQueryCondition
    {
        RuntimeStatus = new[]
        {
            OrchestrationRuntimeStatus.Pending,
            OrchestrationRuntimeStatus.Running,
        },
        CreatedTimeFrom = DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)),
        CreatedTimeTo = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
        PageSize = 100,
    };
    
    OrchestrationStatusQueryResult result = await client.ListInstancesAsync(
        queryFilter,
        CancellationToken.None);
    foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState)
    {
        log.LogInformation(JsonConvert.SerializeObject(instance));
    }
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

Azure Functions Core Tools

在 Azure Functions Core Tools 中,您也可以使用 durable get-instances 命令搭配篩選條件。 除了前述的 topcontinuation-tokenconnection-string-settingtask-hub-name 參數之外,您還可以使用三個篩選條件參數 (created-aftercreated-beforeruntime-status)。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

以下是 durable get-instances 命令的參數。

  • created-after (選用):擷取這個日期/時間 (UTC) 之後建立的執行個體。 可接受 ISO 8601 格式的日期時間。
  • created-before (選用):擷取這個日期/時間 (UTC) 之前建立的執行個體。 可接受 ISO 8601 格式的日期時間。
  • runtime-status (選用):擷取具有特定狀態的執行個體 (例如,執行中或已完成)。 可以提供多個狀態 (以空格分隔)。
  • top (選用):每個要求擷取的執行個體數目。 預設值為 10。
  • continuation-token (選用):用來指出所要擷取執行個體頁面或區段的權杖。 每個 get-instances 執行都會將權杖傳回給下一組執行個體。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設值為 DurableFunctionsHub。 也可以在 host.json 中使用 durableTask:HubName 來進行設定。

如果您未提供任何篩選條件 (created-aftercreated-beforeruntime-status),則不論執行階段狀態或建立時間,該命令只會擷取 top 執行個體。

func durable get-instances --created-after 2021-03-10T13:57:31Z --created-before  2021-03-10T23:59Z --top 15

終止執行個體

如果您有耗時太久才執行的協調流程執行個體,或者只是需要在執行個體完成之前停止執行 (不論原因),您可以終止執行個體。

終止 API 的兩個參數是 instance ID 和 reason 字串,其會寫入記錄和執行個體狀態。

[FunctionName("TerminateInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("terminate-queue")] string instanceId)
{
    string reason = "Found a bug";
    return client.TerminateAsync(instanceId, reason);
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

終止的執行個體最終會轉換為 Terminated 狀態。 不過,轉換不會立即發生。 實際上,終止作業會與該執行個體的其他作業一起排入工作中樞佇列。 您可以使用執行個體查詢 API 來得知終止的執行個體實際觸達 Terminated 狀態的時間。

注意

執行個體終止目前不會散佈。 無論您是否已終止呼叫活動函式和子協調流程的協調流程執行個體,這些活動函式和子協調流程皆會執行到完成為止。

暫止和繼續執行個體

暫止協調流程可讓您停止執行中的協調流程。 不同於終止,您可以選擇在之後的時間點繼續暫止的協調器。

暫止 API 的兩個參數為執行個體識別碼和原因字串,會寫入記錄和執行個體狀態。

[FunctionName("SuspendResumeInstance")]
public static async Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("suspend-resume-queue")] string instanceId)
{
    // To suspend an orchestration
    string suspendReason = "Need to pause workflow";
    await client.SuspendAsync(instanceId, suspendReason);
    
    // To resume an orchestration
    string resumeReason = "Continue workflow";
    await client.ResumeAsync(instanceId, resumeReason);
}

暫止的執行個體最終會轉換為 Suspended 狀態, 不過,轉換不會立即發生。 實際上,暫止作業會與該執行個體的其他作業一起排入工作中樞佇列。 您可以使用執行個體查詢 API 了解執行中的執行個體實際進入「暫止」狀態的時間。

當暫止的協調器繼續,其狀態會變更回 Running

Azure Functions Core Tools

您也可以使用 Core Tools 中的 func durable terminate 命令,直接終止協調流程執行個體。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable terminate 命令採用下列參數:

  • id (必要):要終止的協調流程執行個體識別碼。
  • reason (選用):終止原因。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設值為 DurableFunctionsHub。 也可以在 host.json 中使用 durableTask:HubName 來進行設定。

下列命令會終止識別碼為 0ab8c55a66644d68a3a8b220b12d209c 的協調流程執行個體:

func durable terminate --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Found a bug"

將事件傳送至執行個體

在某些情況下,協調器函式必須等候並接聽外部事件。 適用的範例案例包括監視人為互動等。

您可以使用協調流程用戶端的「引發事件」 API,將事件通知傳送至執行中的執行個體。 協調流程可以使用「等候外部事件」協調器 API 來接聽和回應這些事件。

「引發事件」的參數如下所示:

  • Instance ID:執行個體的唯一識別碼。
  • Event name:要傳送的事件名稱。
  • Event data:要傳送至執行個體的 JSON 可序列化承載。
[FunctionName("RaiseEvent")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("event-queue")] string instanceId)
{
    int[] eventData = new int[] { 1, 2, 3 };
    return client.RaiseEventAsync(instanceId, "MyEvent", eventData);
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

注意

如果沒有具有指定「執行個體識別碼」的協調流程執行個體,則會捨棄事件訊息。 如果執行個體存在,但尚未等候事件,事件將會儲存在執行個體狀態,直到準備好接收和處理為止。

Azure Functions Core Tools

您也可以使用 Core Tools 中的 func durable raise-event 命令,直接引發事件到協調流程執行個體。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable raise-event 命令採用下列參數:

  • id (必要):協調流程執行個體的識別碼。
  • event-name:所要引發事件的名稱。
  • event-data (選用):要傳送至協調流程執行個體的資料。 這可以是 JSON 檔案的路徑,或您也可以直接在命令列上提供資料。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設值為 DurableFunctionsHub。 也可以在 host.json 中使用 durableTask:HubName 來進行設定。
func durable raise-event --id 0ab8c55a66644d68a3a8b220b12d209c --event-name MyEvent --event-data @eventdata.json
func durable raise-event --id 1234567 --event-name MyOtherEvent --event-data 3

等候協調流程完成

在長時間執行的協調流程中,您可能需要等候以取得協調流程的結果。 在這些情況下,能夠在協調流程上定義逾時期間也是相當有用的。 如果超過逾時期間,系統應該傳回協調流程的狀態,而非結果。

「等候完成或建立檢查狀態回應」API 可用來同步取得協調流程執行個體的實際輸出。 根據預設,此方法的預設逾時為 10 秒,輪詢間隔為 1 秒。

以下是範例 HTTP 觸發函式,它會示範如何使用這個 API:

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;

namespace VSSample
{
    public static class HttpSyncStart
    {
        private const string Timeout = "timeout";
        private const string RetryInterval = "retryInterval";

        [FunctionName("HttpSyncStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/wait")]
            HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            TimeSpan timeout = GetTimeSpan(req, Timeout) ?? TimeSpan.FromSeconds(30);
            TimeSpan retryInterval = GetTimeSpan(req, RetryInterval) ?? TimeSpan.FromSeconds(1);
            
            return await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(
                req,
                instanceId,
                timeout,
                retryInterval);
        }

        private static TimeSpan? GetTimeSpan(HttpRequestMessage request, string queryParameterName)
        {
            string queryParameterStringValue = request.RequestUri.ParseQueryString()[queryParameterName];
            if (string.IsNullOrEmpty(queryParameterStringValue))
            {
                return null;
            }

            return TimeSpan.FromSeconds(double.Parse(queryParameterStringValue));
        }
    }
}

使用下列程式碼呼叫函式。 請將逾時設為 2 秒,重試間隔設為 0.5 秒:

curl -X POST "http://localhost:7071/orchestrators/E1_HelloSequence/wait?timeout=2&retryInterval=0.5"

注意

上述 cURL 命令假設您在專案中有名為 E1_HelloSequence 的協調器函式。 由於 HTTP 觸發程序函數的撰寫方式,您可以將其取代為專案中任何協調器函式的名稱。

取決於從協調流程執行個體取得回應所需的時間,會有兩種情況:

  • 協調流程執行個體在定義的逾時 (在此案例中為 2 秒) 內完成,且回應是實際的協調流程執行個體輸出,以同步方式傳遞:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:14:29 GMT
Transfer-Encoding: chunked

[
    "Hello Tokyo!",
    "Hello Seattle!",
    "Hello London!"
]
  • 協調流程執行個體無法在定義的逾時內完成,且回應是在 HTTP API URL 探索中說明的預設值一:
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Date: Thu, 14 Dec 2021 06:13:51 GMT
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}
Retry-After: 10
Transfer-Encoding: chunked

{
    "id": "d3b72dddefce4e758d92f4d411567177",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/raiseEvent/{eventName}?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177?taskHub={taskHub}&connection={connection}&code={systemKey}",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/terminate?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "suspendPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/suspend?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}",
    "resumePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d3b72dddefce4e758d92f4d411567177/resume?reason={text}&taskHub={taskHub}&connection={connection}&code={systemKey}"
}

注意

Webhook URL 的格式依您執行的 Azure Functions 主機版本,可能會有所不同。 上述範例適用於 Azure Functions 3.0 主機。

擷取 HTTP 管理 Webhook URL

您可以使用外部系統來監視或引發事件至協調流程。 外部系統可透過 Webhook URL 與 Durable Functions 通訊, 這些 Webhook URL 包含在 HTTP API URL 探索所說明的預設回應中。 您也可以使用協調流程用戶端繫結,以程式設計的方式存取 Webhook URL。 具體而言,「建立 HTTP 管理承載」 API 可用來取得包含這些 Webhook URL 的可序列化物件。

「建立 HTTP 管理承載」 API 有一個參數:

  • Instance ID:執行個體的唯一識別碼。

此方法會傳回具有下列字串屬性的物件:

  • Id:協調流程的執行個體識別碼 (應該與 InstanceId 輸入相同)。
  • StatusQueryGetUri:協調流程執行個體的狀態 URL。
  • SendEventPostUri:協調流程執行個體的「引發事件」URL。
  • TerminatePostUri:協調流程執行個體的「終止」URL。
  • PurgeHistoryDeleteUri:協調流程執行個體的「清除歷程記錄」URL。
  • suspendPostUri:協調流程執行個體的「暫止」URL。
  • resumePostUri:協調流程執行個體的「繼續」URL。

函式可以將這些物件的執行個體傳送至外部系統,以監視或引發對應協調流程上的事件,如下列範例所示:

[FunctionName("SendInstanceInfo")]
public static void SendInstanceInfo(
    [ActivityTrigger] IDurableActivityContext ctx,
    [DurableClient] IDurableOrchestrationClient client,
    [CosmosDB(
        databaseName: "MonitorDB",
        containerName: "HttpManagementPayloads",
        Connection = "CosmosDBConnectionSetting")]out dynamic document)
{
    HttpManagementPayload payload = client.CreateHttpManagementPayload(ctx.InstanceId);

    // send the payload to Azure Cosmos DB
    document = new { Payload = payload, id = ctx.InstanceId };
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableActivityContext 而非 IDurableActivityContext,而且必須使用 OrchestrationClient 屬性,而非 DurableClient 屬性,且必須使用 DurableOrchestrationClient 參數類型,而非 IDurableOrchestrationClient。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

倒轉執行個體 (預覽)

如果您因非預期的原因發生協調流程失敗,可以使用針對該用途建置的 API,將執行個體「倒轉」回先前的健全狀態。

注意

此 API 並非要取代適當的錯誤處理和重試原則。 相反地,它只是要用於協調流程執行個體因非預期原因而失敗的情況。 處於 Failed 以外之狀態 (例如 RunningPendingTerminatedCompleted) 的協調流程無法「倒轉」。 如需錯誤處理和重試原則的詳細資訊,請參閱錯誤處理文章。

使用協調流程用戶端繫結RewindAsync (.NET) 或 rewind(JavaScript) 方法,將協調流程倒轉回到「執行中」狀態。 此方法也會重新執行造成協調流程失敗的活動或子協調流程執行失敗。

例如,假設您有涉及一連串人為核准的工作流程。 假設有一系列的活動函式,其可通知某人需要其核准並等待即時回應。 在所有核准活動收到回應或逾時之後,假設另一個活動因為應用程式設定錯誤 (例如資料庫連接字串無效) 而失敗。 結果就是深入工作流程的協調流程失敗。 透過 RewindAsync (.NET) 或 rewind (JavaScript) API,應用程式系統管理員可以修正設定錯誤,並讓失敗的協調流程「倒轉」回失敗之前的狀態。 不需要重新核准任何人為互動步驟,協調流程現在可以順利完成了。

注意

「倒轉」功能不支援使用耐久計時器來倒轉協調流程執行個體。

[FunctionName("RewindInstance")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("rewind-queue")] string instanceId)
{
    string reason = "Orchestrator failed and needs to be revived.";
    return client.RewindAsync(instanceId, reason);
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

Azure Functions Core Tools

您也可以使用 Core Tools 中的 func durable rewind 命令,直接倒轉協調流程執行個體。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable rewind 命令採用下列參數:

  • id (必要):協調流程執行個體的識別碼。
  • reason (選用):倒轉協調流程執行個體的原因。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設會使用 host.json 檔案中的工作中樞名稱。
func durable rewind --id 0ab8c55a66644d68a3a8b220b12d209c --reason "Orchestrator failed and needs to be revived."

清除執行個體歷程記錄

若要移除與協調流程相關的所有資料,您可以清除執行個體歷程記錄。 例如,您可能想刪除與已完成執行個體相關的任何儲存體資源。 若要這樣做,請使用協調流程用戶端 所定義的「清除執行個體」 API。

第一個範例示範如何清除單一協調流程執行個體。

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [QueueTrigger("purge-queue")] string instanceId)
{
    return client.PurgeInstanceHistoryAsync(instanceId);
}

下一個範例會顯示計時器觸發的函式,它會清除所有在指定時間間隔之後完成的協調流程執行個體歷程記錄。 在此案例中,它會移除已完成 30 天以上所有執行個體的資料。 此範例函式排程在每天下午 12:00 UTC 執行一次:

[FunctionName("PurgeInstanceHistory")]
public static Task Run(
    [DurableClient] IDurableOrchestrationClient client,
    [TimerTrigger("0 0 12 * * *")] TimerInfo myTimer)
{
    return client.PurgeInstanceHistoryAsync(
        DateTime.MinValue,
        DateTime.UtcNow.AddDays(-30),  
        new List<OrchestrationStatus>
        {
            OrchestrationStatus.Completed
        });
}

注意

先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient 屬性 (而非 DurableClient 屬性),而且必須使用 DurableOrchestrationClient 參數類型 (而非 IDurableOrchestrationClient)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。

注意

若要讓清除歷程記錄作業成功,目標執行個體的執行階段狀態必須是 [已完成]、[已終止] 或 [已失敗]

Azure Functions Core Tools

您可以在 Core Tools 中使用 func durable purge-history 命令來清除協調流程執行個體的歷程記錄。 與前一節的第二個 C# 範例類似,此命令會清除在指定的時間間隔期間所建立的所有協調流程執行個體的歷程記錄。 您可以依執行階段狀態進一步篩選清除的執行個體。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable purge-history 命令有數個參數:

  • created-after (選用):清除這個日期/時間 (UTC) 之後所建立執行個體的記錄。 可接受 ISO 8601 格式的日期時間。
  • created-before (選用):清除這個日期/時間 (UTC) 之前所建立執行個體的記錄。 可接受 ISO 8601 格式的日期時間。
  • runtime-status (選用):清除具有特定狀態 (例如,執行中或已完成) 的執行個體歷程記錄。 可以提供多個狀態 (以空格分隔)。
  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設會使用 host.json 檔案中的工作中樞名稱。

下列命令會刪除 2021 年 11 月 14 日下午 7:35 (UTC) 以前建立的所有失敗執行個體的歷程記錄。

func durable purge-history --created-before 2021-11-14T19:35:00.0000000Z --runtime-status failed

刪除工作中樞

在 Core Tools 中使用 func durable delete-task-hub 命令,您可以刪除與特定工作中樞相關的所有儲存體成品,包括 Azure 儲存體資料表、佇列和 Blobs。

注意

目前只有在使用預設的 Azure 儲存體提供者來保存執行階段狀態時,才會支援 Core Tools 命令。

durable delete-task-hub 命令有兩個參數:

  • connection-string-setting (選用):應用程式設定的名稱,包含要使用的儲存體連接字串。 預設值為 AzureWebJobsStorage
  • task-hub-name (選用):要使用的 Durable Functions 工作中樞名稱。 預設會使用 host.json 檔案中的工作中樞名稱。

下列命令會將與 UserTest 工作中樞相關的所有 Azure 儲存體資料刪除。

func durable delete-task-hub --task-hub-name UserTest

下一步