タイマーを使用して実行時間の長いタスクを制御する

完了

実行時間の長いワークフローを使用する場合は、いくつかの追加シナリオを検討することが重要です。 たとえば、タスクが許容時間内に完了しなかった場合はどうなるでしょうか。 タスクの状態を確認するにはどうすればよいでしょうか。 タイムアウトとエスカレーション パスでこのような問題に対処できます。

このシナリオ例で、あなたは、プロジェクト設計提案が適切なタイミングで承認されない場合にアクションを実行するエスカレーション手順を組み込む、という新しいワークフローの修正を依頼されました。

このユニットでは、持続的タイマーを使用して実行時間の長いタスクを制御する方法と、タイマーに基づいてエスカレーション パスを追加する方法を学習します。

Durable Functions のタイマー

Durable Functions には、オーケストレーター関数で使用するためのタイマーが用意されています。これを使って遅延を実装したり、非同期操作のタイムアウトを設定したりできます。 setTimeout()setInterval() 関数の代わりに、オーケストレーター関数の持続的タイマーを使用する必要があります。

持続的タイマーは、DurableOrchestrationContextcreateTimer() メソッドを呼び出すと作成できます。 このメソッドは、指定した日時に再開するタスクを返します。

遅延にタイマーを使用する

次の例は、遅延用に持続的タイマーを使用する方法を示しています。10 日間毎日リマインダーが送信されます。

const df = require("durable-functions");
const moment = require("moment");

module.exports = df.orchestrator(function*(context) {
    for (let i = 0; i < 10; i++) {
        const deadline = moment.utc(context.df.currentUtcDateTime).add(i, 'd');
        yield context.df.createTimer(deadline.toDate());
        yield context.df.callActivity("SendReminder");
    }
});

現在の日付と時刻を取得するには、Date.nowDate.UTC ではなく、常に currentUtcDateTime を使用する必要があります。

タイムアウトにタイマーを使用する

次の例は、タイムアウト用に持続的タイマーを使用する方法を示しています。タイムアウトが発生した場合は、別のパスが実行されます。 この例では、GetQuote アクティビティ関数が完了するか、deadline タイマーが期限切れになるまで関数は待機します。 アクティビティ関数が完了した場合、コードは success case に進みます。そうでない場合は timeout case に進みます。

const df = require("durable-functions");
const moment = require("moment");

module.exports = df.orchestrator(function*(context) {
    const deadline = moment.utc(context.df.currentUtcDateTime).add(30, "s");

    const activityTask = context.df.callActivity("GetQuote");
    const timeoutTask = context.df.createTimer(deadline.toDate());

    const winner = yield context.df.Task.any([activityTask, timeoutTask]);
    if (winner === activityTask) {
        // success case
        timeoutTask.cancel();
        return true;
    }
    else
    {
        // timeout case
        return false;
    }
});

次の演習では、この情報を使用して、オーケストレーター関数のサンプル シナリオにエスカレーション パスを追加します。