練習 - 新增持久計時器來管理長時間執行的工作
公司已要求修改新工作流程來納入呈報步驟,以在專案設計提案未及時獲得核准時採取動作。
在本練習中,您將新增計時器來控制工作流程執行時的逾時。 您也會了解如何使用逾時來控制工作流程會採用的執行路徑。
將 moment npm 套件新增至您的函數應用程式
在變更工作流程之前,我們將透過主控台將 moment npm 套件新增至函數應用程式。
使用啟用沙箱時所用的相同帳戶來登入 Azure 入口網站。
在 Azure 入口網站功能表或 [首頁] 頁面的 [Azure 服務] 中,選取 [所有資源],然後選取在上一個練習中建立的函數應用程式。 您的 [函數應用程式] 窗格隨即出現。
在左側功能表列的 [開發工具] 底下,選取 [主控台]。 函數應用程式的 [主控台] 窗格會隨即出現。
確認主控台視窗是以 C:\home\site\wwwroot 資料夾開啟,然後執行下列命令來安裝此範例函數應用程式所需的程式庫。
執行下列命令來安裝 TypeScript 程式庫,這是靜態類型的必要相依性元件。
npm install typescript
此命令會安裝 moment.js 程式庫,該程式庫包含可與 Durable Functions 搭配使用的日期/時間函式。
npm install moment
這些命令可能需要幾秒的時間才能完成,且節點套件管理員可能會顯示一些您可忽略的警告。
請等待所有套件都完成安裝,然後再關閉主控台視窗。
將呈報活動新增至函數應用程式
在 Azure 入口網站功能表或從 [首頁] 頁面的 [Azure 服務] 下,選取 [所有資源],然後選取函數應用程式。 您的 [函數應用程式] 窗格隨即出現。
選取畫面中央的 [函式] 索引標籤。
在 [函式] 索引標籤功能表列中,選取 [建立]。 [建立函式] 窗格隨即出現。
在 [選取範本] 下的 [篩選] 方塊中,輸入 Durable Functions activity,然後從清單中選取該範本。 此範本會建立耐久的函式,該函式會在協調器函式呼叫活動時執行。
在 [範本詳細資料] 下的 [新增函式] 欄位中,輸入函式名稱 Escalation,然後選取 [建立]。 函式的 [Escalation] 窗格會隨即出現。
在左側功能表窗格中,於 [開發人員] 底下,選取 [程式碼 + 測試]。 適用於您函式的 [編碼 + 測試] 窗格隨即出現。
index.js 檔案的程式碼隨即會出現在編輯器中。
將現有的程式碼取代為下列程式碼:
module.exports = async function (context) { return `ESCALATION : You have not approved the project design proposal - reassigning to your Manager! ${context.bindings.name}!`; };
此程式碼會傳回指出已將工作流程呈報的訊息。 在生產系統中,此函式會包含提醒收件者或重新指派工作的邏輯。
請從頂端功能表列選取 [儲存],儲存新函式。
將協調流程函式更新成使用呈報函式
在 Azure 入口網站功能表或從 [首頁] 頁面的 [Azure 服務] 下,選取 [所有資源],然後選取函數應用程式。 您的 [函數應用程式] 窗格隨即出現。
選取畫面中央的 [函式] 索引標籤。
選取在上一個練習中建立的 OrchFunction 函式。 [OrchFunction] 函式窗格會隨即出現。
在左側功能表窗格中,於 [開發人員] 底下,選取 [程式碼 + 測試]。 適用於您函式的 [編碼 + 測試] 窗格隨即出現。
index.js 檔案的程式碼隨即會出現在編輯器中。
新增下列 moment 程式庫參考。
const moment = require("moment");
將函式的主體取代為下列程式碼,以測試是否已超過核准期限:
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 的呼叫變更為等候外部輸入。 如此一來,我們便可以針對測試目的,控制何時傳回回應。
在頂端功能列上,選取 [儲存]。
確認 Durable Functions 工作流程開始
在 Azure 入口網站功能表或從 [首頁] 頁面的 [Azure 服務] 下,選取 [所有資源],然後選取函數應用程式。 您的 [函數應用程式] 窗格隨即出現。
在 [概觀] 窗格的頂端功能表列上,選取 [重新啟動],然後在系統提示重新啟動時,選取 [是]。 等候重新啟動完成,再繼續進行操作。 [函數應用程式] 窗格會隨即出現。
選取畫面中央的 [函式] 索引標籤。
選取 HttpStart 函式。 [HttpStart] 窗格會隨即出現。
在頂端功能表列上,選取 [取得函式 URL],然後複製 URL。 URL 應該類似下列範例:
https://example.azurewebsites.net/api/orchestrators/{functionName}?code=AbCdEfGhIjKlMnOpQrStUvWxYz==
您將使用此 URL 執行您的函式。
開啟新的瀏覽器視窗,然後引導至所複製的 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/..." }
複製 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" }
等候 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" }