練習 - 新增持久計時器來管理長時間執行的工作

已完成

公司已要求修改新工作流程來納入呈報步驟,以在專案設計提案未及時獲得核准時採取動作。

在本練習中,您將新增計時器來控制工作流程執行時的逾時。 您也會了解如何使用逾時來控制工作流程會採用的執行路徑。

將 moment npm 套件新增至您的函數應用程式

在變更工作流程之前,我們將透過主控台將 moment npm 套件新增至函數應用程式。

  1. 使用啟用沙箱時所用的相同帳戶來登入 Azure 入口網站

  2. 在 Azure 入口網站功能表或 [首頁] 頁面的 [Azure 服務] 中,選取 [所有資源],然後選取在上一個練習中建立的函數應用程式。 您的 [函數應用程式] 窗格隨即出現。

  3. 在左側功能表列的 [開發工具] 底下,選取 [主控台]。 函數應用程式的 [主控台] 窗格會隨即出現。

  4. 確認主控台視窗是以 C:\home\site\wwwroot 資料夾開啟,然後執行下列命令來安裝此範例函數應用程式所需的程式庫。

    1. 執行下列命令來安裝 TypeScript 程式庫,這是靜態類型的必要相依性元件。

      npm install typescript
      
    2. 此命令會安裝 moment.js 程式庫,該程式庫包含可與 Durable Functions 搭配使用的日期/時間函式。

      npm install moment
      

      這些命令可能需要幾秒的時間才能完成,且節點套件管理員可能會顯示一些您可忽略的警告。

  5. 請等待所有套件都完成安裝,然後再關閉主控台視窗。

將呈報活動新增至函數應用程式

  1. 在 Azure 入口網站功能表或從 [首頁] 頁面的 [Azure 服務] 下,選取 [所有資源],然後選取函數應用程式。 您的 [函數應用程式] 窗格隨即出現。

  2. 選取畫面中央的 [函式] 索引標籤。

  3. [函式] 索引標籤功能表列中,選取 [建立]。 [建立函式] 窗格隨即出現。

  4. [選取範本] 下的 [篩選] 方塊中,輸入 Durable Functions activity,然後從清單中選取該範本。 此範本會建立耐久的函式,該函式會在協調器函式呼叫活動時執行。

  5. 在 [範本詳細資料] 下的 [新增函式] 欄位中,輸入函式名稱 Escalation,然後選取 [建立]。 函式的 [Escalation] 窗格會隨即出現。

  6. 在左側功能表窗格中,於 [開發人員] 底下,選取 [程式碼 + 測試]。 適用於您函式的 [編碼 + 測試] 窗格隨即出現。

    index.js 檔案的程式碼隨即會出現在編輯器中。

  7. 將現有的程式碼取代為下列程式碼:

    module.exports = async function (context) {
        return `ESCALATION : You have not approved the project design proposal - reassigning to your Manager!  ${context.bindings.name}!`;
    };
    

    此程式碼會傳回指出已將工作流程呈報的訊息。 在生產系統中,此函式會包含提醒收件者或重新指派工作的邏輯。

  8. 請從頂端功能表列選取 [儲存],儲存新函式。

將協調流程函式更新成使用呈報函式

  1. 在 Azure 入口網站功能表或從 [首頁] 頁面的 [Azure 服務] 下,選取 [所有資源],然後選取函數應用程式。 您的 [函數應用程式] 窗格隨即出現。

  2. 選取畫面中央的 [函式] 索引標籤。

  3. 選取在上一個練習中建立的 OrchFunction 函式。 [OrchFunction] 函式窗格會隨即出現。

  4. 在左側功能表窗格中,於 [開發人員] 底下,選取 [程式碼 + 測試]。 適用於您函式的 [編碼 + 測試] 窗格隨即出現。

    index.js 檔案的程式碼隨即會出現在編輯器中。

  5. 新增下列 moment 程式庫參考。

    const moment = require("moment");
    
  6. 將函式的主體取代為下列程式碼,以測試是否已超過核准期限:

    module.exports = df.orchestrator(function* (context) {
        const outputs = [];
        const deadline = moment.utc(context.df.currentUtcDateTime).add(20, "s");
        const activityTask = context.df.waitForExternalEvent("Approval");
        const timeoutTask = context.df.createTimer(deadline.toDate());
    
        const winner = yield context.df.Task.any([activityTask, timeoutTask]);
        if (winner === activityTask) {
            outputs.push(yield context.df.callActivity("Approval", "Approved"));
        }
        else
        {
            outputs.push(yield context.df.callActivity("Escalation", "Head of department"));
        }
    
        if (!timeoutTask.isCompleted) {
            // All pending timers must be complete or canceled before the function exits.
            timeoutTask.cancel();
        }
    
        return outputs;
    });
    

    針對本練習的目的,為了簡潔起見,如果 Approval 函式未在 20 秒內回應,即會呼叫 Escalation 函式。 此程式碼也會將對 Approval 的呼叫變更為等候外部輸入。 如此一來,我們便可以針對測試目的,控制何時傳回回應。

  7. 在頂端功能列上,選取 [儲存]

確認 Durable Functions 工作流程開始

  1. 在 Azure 入口網站功能表或從 [首頁] 頁面的 [Azure 服務] 下,選取 [所有資源],然後選取函數應用程式。 您的 [函數應用程式] 窗格隨即出現。

  2. 在 [概觀] 窗格的頂端功能表列上,選取 [重新啟動],然後在系統提示重新啟動時,選取 [是]。 等候重新啟動完成,再繼續進行操作。 [函數應用程式] 窗格會隨即出現。

  3. 選取畫面中央的 [函式] 索引標籤。

  4. 選取 HttpStart 函式。 [HttpStart] 窗格會隨即出現。

  5. 在頂端功能表列上,選取 [取得函式 URL],然後複製 URL。 URL 應該類似下列範例:

    https://example.azurewebsites.net/api/orchestrators/{functionName}?code=AbCdEfGhIjKlMnOpQrStUvWxYz==
    

    您將使用此 URL 執行您的函式。

  6. 開啟新的瀏覽器視窗,然後引導至所複製的 URL。 在 URL 中,將 {functionName} 預留位置取代為 OrchFunction,其應類似下列範例所示:

    https://example.azurewebsites.net/api/orchestrators/OrchFunction?code=AbCdEfGhIjKlMnOpQrStUvWxYz==
    

    回應訊息包含一組可用於監視和管理執行的 URI 端點,如下列範例所示:

    {
      "id": "f0e1d2c3b4a5968778695a4b3c2d1e0f",
      "statusQueryGetUri": "https://example.azurewebsites.net/...",
      "sendEventPostUri": "https://example.azurewebsites.net/...",
      "terminatePostUri": "https://example.azurewebsites.net/...",
      "rewindPostUri": "https://example.azurewebsites.net/...",
      "purgeHistoryDeleteUri": "https://example.azurewebsites.net/..."
    }
    
  7. 複製 statusQueryGetUri 值,然後使用您的網頁瀏覽器來瀏覽至該 URL。 您應該會看到一則回應訊息,顯示函式因正在等候計時器倒數 20 秒而處於 Running (執行中) 狀態,其應類似下列範例所示:

    {
      "name": "OrchFunction",
      "instanceId": "f0e1d2c3b4a5968778695a4b3c2d1e0f",
      "runtimeStatus": "Running",
      "input": null,
      "customStatus": null,
      "output": null,
      "createdTime": "2019-04-14T13:17:26Z",
      "lastUpdatedTime": "2019-04-14T13:17:27Z"
    }
    
  8. 等候 20 秒,然後重新整理瀏覽器視窗。 經過逾時後,接著工作流程會呼叫 Escalate 活動。 您會看到如下列範例所示的回應:

    {
        "name": "OrchFunction",
        "instanceId": "f0e1d2c3b4a5968778695a4b3c2d1e0f",
        "runtimeStatus": "Completed",
        "input": null,
        "customStatus": null,
        "output": [
            "ESCALATION : You have not approved the project design proposal - reassigning to your Manager!  Head of department!"
        ],
        "createdTime": "2019-04-14T13:43:09Z",
        "lastUpdatedTime": "2019-04-14T13:43:31Z"
    }