$30 off During Our Annual Pro Sale. View Details »

世界一わかりみの深いDurable Functions/wakarimi_durablefunctions

Noriyuki TAKEI
February 03, 2022

世界一わかりみの深いDurable Functions/wakarimi_durablefunctions

Noriyuki TAKEI

February 03, 2022
Tweet

More Decks by Noriyuki TAKEI

Other Decks in Technology

Transcript

  1. View Slide

  2. BCPVUNF
    Noriyuki TAKEI
    ෢Ҫ ٓߦ
    Information
    • サイオステクノロジー株式会社
    • Microsoft MVP for Azure
    Favorites
    • Azure
    • Squash
    • Sweets
    • Running
    blog
    https://tech-lab.sios.jp/ core skill
    Container、Cloud Native、
    Serverless全般
    Twitter
    @noriyukitakei

    View Slide

  3. 技術ブログ「SIOS Tech.Lab」
    多分わかりやすいDurable Functions
    https://tech-lab.sios.jp/archives/12991

    View Slide

  4. 用語解説
    Durable Functionsとは?
    オーケストレーター関数
    アクティビティ関数
    アクティビティ関数
    アクティビティ関数
    アクティビティ関数
    アクティビティ関数
    アクティビティ関数

    View Slide

  5. Durable Functionsとは?
    ฏͨ͘ݴ͏ͱɺɺɺ
    "[VSF'VODUJPOT͚ͩͰ࣮ݱ͠Α͏
    ͱ͢Δͱɺ΋ͷ͘͢͝ෳࡶͳίʔυʹ
    ͳͬͯ͠·͏Α͏ͳ
    ෳࡶͳॲཧ͕ɺ%VSBCMF'VODUJPOTΛ
    ࢖͏ͱɺ͘͢͝୹͍ίʔυͰ؆୯ʹ
    ࣮ݱͰ͖Δɻ
    ͔͠΋αʔόʔϨεͰɻ

    View Slide

  6. Azure Functionsとは?
    サーバーが不要!!
    before
    • 仮想マシン作成
    • OSインストール
    • ミドルウェア(Apache
    等)インストール
    • 性能検証
    • コーディング
    after
    ブラウザ上、もしくは専
    ⽤の開発環境でコードを
    ⼊⼒して保存するだ
    け︕︕
    アプリ開発の⼿間を⼤幅に削減︕︕

    View Slide

  7. Azure Functionsとは?
    必要に応じてスケール︕︕
    before
    • 負荷テストツール⽤意
    • テストシナリオ作成
    • テスト実施
    • チューニング
    • 結果報告書作成
    after
    特別な設定は不要︕︕負
    荷に応じてほぼ無限にス
    ケール︕︕
    負荷に応じて無限にスケールします。

    View Slide

  8. Azure Functionsとは?
    使った分だけ課⾦︕︕
    before
    仮想マシンの場合、アプリ
    ケーションが動いてなくて
    も、仮想マシンが起動して
    いる時間だけ課⾦が発⽣す
    る。
    after
    アプリケーションが動い
    た時間だけしか課⾦され
    ないので、仮想マシンと
    ⽐べて料⾦が抑えられる。
    使った分だけ課⾦します。

    View Slide

  9. Azure Functionsでこんなアプリを作ってみたい
    グループA
    グループB
    グループA
    ユーザーA
    グループB
    ユーザーB

    Azure FunctionsでAzure
    Active Directoryにグループ
    を作成する。

    先程作成したグループに
    Azure Functionsでユーザー
    を追加する。
    グループの追加が全て完了したら・・・

    View Slide

  10. View Slide

  11. Azure Functionsでこんなアプリを作ってみたい
    グループA
    グループB
    グループA
    ユーザーA
    グループB
    ユーザーB

    Azure FunctionsでAzure
    Active Directoryにグループ
    を作成する。

    先程作成したグループに
    Azure Functionsでユーザー
    を追加する。
    ここが
    難しい!!
    グループの追加が全て完了したら・・・

    View Slide

  12. Durable
    Functionsが
    解決!!

    View Slide

  13. 前のAzure Functionsが終わるのを待って、次のAzure Functionsを起動で
    きる。
    並列実⾏しているAzure Functionsが全て終わるのを待ってから、次の
    Azure Functionsを起動できる。
    XX時間内に外部からのイベントがない場合は、別の処理を⾏うなんてこ
    ともできる。
    Durable Functionsでは、こんなことができます!!

    View Slide

  14. © SIOS Technology Inc. All rights Reserved.
    Durable Functionsの実装パターン
    14

    View Slide

  15. nori
    “Hello” + $x
    Hello nori
    $x + “. How are you?”
    Hello nori.
    How are
    you?
    sayHello関数 sayHowAreYou関数
    関数チェーン
    関数チェーンは、特定の順序で関数のシーケンスを実⾏するパターンです。

    View Slide

  16. 関数チェーン(実装)
    const df = require("durable-functions");
    module.exports = df.orchestrator(function*(ctx) {
    const x = yield ctx.df.callActivity(“sayHello”,”nori”);
    const y = yield ctx.df.callActivity(“sayHowAreYou”, x);
    return y;
    });

    View Slide

  17. ファンアウト/ファンイン
    ファンアウト/ファンインは、複数の関数を並列に実⾏してすべてが完了するまで待機するパターン
    です。
    favoriteFruits関数
    favorite
    Vegetables関数
    apple
    tomato
    I like an
    tomat and
    an apple

    View Slide

  18. ファンアウト/ファンイン(実装)
    const df = require("durable-functions");
    module.exports = df.orchestrator(function* (ctx) {
    const parallelTasks = [];
    parallelTasks.push(ctx.df.callActivity("favoriteFruits"));
    parallelTasks.push(ctx.df.callActivity("favoriteVegetables"));
    const results = yield ctx.df.Task.all(parallelTasks);
    ctx.log('I like an ' + results[0] + ' and an ' + results[1]);
    });

    View Slide

  19. 人による操作
    ある関数を実⾏してから、⼈による操作(承認⾏為など)などがなされてから初めて次の関数を実⾏し
    ます。

    View Slide

  20. 人による操作(実装)
    const df = require("durable-functions");
    const moment = require('moment');
    module.exports = df.orchestrator(function* (context) {
    yield context.df.callActivity("gatherCode");
    const expiration = moment.utc(context.df.currentUtcDateTime).add(90, 's');
    const timeoutTask = context.df.createTimer(expiration.toDate());
    const challengeResponseTask = context.df.waitForExternalEvent("Response");
    const winner = yield context.df.Task.any([challengeResponseTask, timeoutTask]);
    if (winner === challengeResponseTask) {
    // Do Smething
    }
    });

    View Slide

  21. © SIOS Technology Inc. All rights Reserved.
    Durable Functionsの構成
    21

    View Slide

  22. オーケストレーター関数を起動するための関数です。この関数
    を起動するトリガーはAzure Functionsで利⽤する全てものも
    を利⽤できます。
    クライアント
    関数
    アクティビティ関数を起動するための関数です。アクティビ
    ティ関数のオーケストレーター的な役割をします。例えば、ア
    クティビティ関数の結果を受け取って、それを他のアクティビ
    ティ関数に渡したりとか、全てのアクティビティ関数の終了を
    待ってから処理を⾏うとか、⾊々な制御ができます。オーケス
    トレーター関数では実際の処理は⾏いません。あくまで、アク
    ティビティ関数のコントロールです。
    オーケストレーター
    関数
    実際の処理を⾏う関数です。
    アクティビティ
    関数
    Durable Functionsの構成

    View Slide

  23. Durable Functionsの構成

    View Slide

  24. 以下の要件のDurable Functionsを考えてみよう!!
    「URLのクエリパラメーターnumに指定された数
    字に2を⾜し、さらにその数字に2をかける処理を
    実⾏する。」という簡単な要件をDurable
    Functionsで実⾏してみる。

    View Slide

  25. HTTPトリガーで起動し、クエリパラメーターnumに指定され
    た数字をオーケストレーター関数に渡す。
    クライアント
    関数
    クライアント関数から渡された数字を、アクティビティ関数
    1(後述)の引数に渡して実⾏し、さらにその結果をアクティビ
    ティ関数2(後述)の引数に渡して実⾏する。
    オーケストレーター
    関数
    引数に渡された数字に2を⾜すアクティビティ関数1と、引数に
    渡された数字に2をかけるアクティビティ関数2の2つの関数か
    ら構成される。
    アクティビティ
    関数
    Durable Functionsの構成

    View Slide

  26. Durable Functionsの構成

    View Slide

  27. © SIOS Technology Inc. All rights Reserved.
    Durable Functionsを動かしてみよう
    27

    View Slide

  28. 以下のユースケースを想定します。
    指定された複数のWebサイトのRSSタグを取得して、「Azure」という
    タグが含まれる記事の合計件数を算出する。
    各WebサイトのRSSタグの取得・合計件数の算出は並列で実⾏する。

    View Slide

  29. 「Azure」というタグの抽出対象に利⽤させて
    頂くWebサイトは以下の2つです。
    サイオステクノロジー技術ブログ
    「SIOS Tech.Lab」 Azureの更新情報

    View Slide

  30. Durable Functionsを
    使わない場合

    View Slide

  31. 必要なもの
    集計対象のWebサイトのRSSタグを取得し、「Azure」という単語が含まれ
    る記事の合計数を算出します。このAzure Functionsは後述するAzure
    Queue Storageでトリガーされ、その結果は、これまた後述するAzure
    Table Storageに格納します
    Azure
    Functions
    先程ご紹介したAzure Functionsは、Azure Queue Storageでトリガーされ
    ます。そのメッセージが格納されるキューになります。
    Azure
    Queue Storage
    先程ご紹介したAzure Functionsは、Webサイトごとの集計結果を、Azure
    のキーバリューストアであるAzure Table Storageに返します。
    Azure Table
    Storage
    Azure Queue Storageにメッセージをプッシュしたり、Azure Table
    Storageに格納された結果を集計したりするアプリケーションです。
    C#で書いた
    アプリ

    View Slide

  32. View Slide

  33. View Slide

  34. View Slide

  35. View Slide

  36. View Slide

  37. Durable Functionsを
    使わない場合は
    仕組みがマジめんどくさい

    View Slide

  38. Durable Functionsを
    使う場合

    View Slide

  39. Azure Queue Storage
    Azure Table Storage
    Azure Functions
    C#で書いた
    アプリ
    オーケストレーター関数で
    置き換え
    アクティビティ関数で
    置き換え


    自分で作る必要
    なし(実際は裏で
    動いている)
    自分で作る必要
    なし(実際は裏で
    動いている)

    View Slide

  40. 必要なもの
    HTTPトリガーで起動し、オーケストレーター関数を起動します。
    クライアント
    関数
    指定された複数のWebサイトのURLをアクティビティ関数の引数に渡して、
    合計数を取得し、それらを全て⾜し合わせる。
    オーケストレーター
    関数
    集計対象のWebサイトのRSSタグを取得し、「Azure」という単語が含まれ
    る記事の合計数を算出します。
    アクティビティ関数

    View Slide

  41. クライント関数
    const df = require("durable-functions");
    module.exports = async function (context, req) {
    const client = df.getClient(context);
    const instanceId = await client.startNew(req.params.functionName, undefined, req.body);
    context.log(`Started orchestration with ID = '${instanceId}'.`);
    return client.createCheckStatusResponse(context.bindingData.req, instanceId);
    };

    View Slide

  42. オーケストレーター関数
    const df = require("durable-functions");
    module.exports = df.orchestrator(function* (context) {
    const tasks = [];
    const urls = ["https://tech-lab.sios.jp/feed/",
    "https://azurecomcdn.azureedge.net/ja-jp/updates/feed/"];
    for(let i = 0; itasks.push(context.df.callActivity("ActivityCountBlog", urls[i]));
    }
    const results = yield context.df.Task.all(tasks);
    const sum = results.reduce((prev, curr) => prev + curr, 0);
    context.log("result:" + sum);
    });

    View Slide

  43. アクティビティ関数
    const Parser = require('rss-parser');
    module.exports = async function (context, RSS) {
    const parser = new Parser();
    let cnt = 0;
    const feed = await parser.parseURL(RSS);
    feed.items.forEach(function (item) {
    if (item.content.indexOf('Azure') != -1)
    cnt++;
    });
    return cnt;
    };

    View Slide

  44. © SIOS Technology Inc. All rights Reserved.
    Durable Functionsの構成要素と
    イベントソーシングについて
    44

    View Slide

  45. 今回の主要な登場人物
    オーケストレーター関数を起動するための関数です。この関数
    を起動するトリガーはAzure Functionsで利⽤する全てものも
    を利⽤できます。
    クライアント
    関数
    アクティビティ関数を起動するための関数です。アクティビ
    ティ関数のオーケストレーター的な役割をします。例えば、ア
    クティビティ関数の結果を受け取って、それを他のアクティビ
    ティ関数に渡したりとか、全てのアクティビティ関数の終了を
    待ってから処理を⾏うとか、⾊々な制御ができます。オーケス
    トレーター関数では実際の処理は⾏いません。あくまで、アク
    ティビティ関数のコントロールです。
    オーケストレーター
    関数
    実際の処理を⾏う関数です。
    アクティビティ
    関数

    View Slide

  46. Durable Functionsの実⾏履歴を記録するAzure Table
    Storageである。オーケストレーター関数やアクティビティ関
    数の実⾏開始終了、出⼒した結果などを逐⼀記録する。
    History Table
    今回の主要な登場人物
    オーケストレーター関数を起動するためのキューであり、オー
    ケストレーター関数はControl Queueのキュートリガーで動作
    する。
    Control Queue
    アクティビティ関数を起動するためのキューであり、アクティ
    ビティ関数はWork Item Queueのキュートリガーで動作する。
    Work Item
    Queue

    View Slide

  47. Durable Functionsの半分は
    イベントソーシングで
    できています。

    View Slide

  48. イベントソーシング
    順番 編集履歴
    1 「こんにちは、たけいさん、ごきげん、い
    かが」と投稿する。
    2 「たけいさん」の部分を「やまださん」と
    編集する。
    3 「ごきげん、いかが」の部分を「ごきげん
    、うるわしゅう」と編集する。
    4 「ごきげん、うるわしゅう」の部分を削除
    する。
    アプリケーションの開発手法の一つで、発生
    したイベントを逐一記録します。
    最新の状態を取得するためには、そのイベン
    トを順次実行(リプレイ)します。
    任意の時点に復元できるというメリットはあ
    りますが、リプレイの仕組みを作成したり、
    リプレイ処理自体に一定の負荷がかかるなど
    デメリットもあります。
    こんにちは、
    やまださん
    ① イベントを逐一記録
    していく。
    ② 今の投稿の最新の状態を取
    得するために、順番に全てのイ
    ベントを実施する。
    ③ これが最新の状態と
    なる。

    View Slide

  49. イベントソーシング
    int result1
    = await context.CallActivityAsync("Plus2", num);
    int result2
    = await context.CallActivityAsync("MultiplyBy2", result1);
    int result3
    = await context.CallActivityAsync("Plus2", result2);
    int result4
    = await context.CallActivityAsync("MultiplyBy2", result3);
    順番 実行関数 結果 戻り値
    1 Plus2 成功 4
    2 MultiplyBy2 成功 8
    3 Plus2 成功 10
    Durable Functionsでは、アクティビティ関数が実行されるごとに、その関数名、結果、戻り値を記録
    していきます。

    View Slide

  50. © SIOS Technology Inc. All rights Reserved.
    Durable Functionsは
    どのように動いているのか?
    50

    View Slide

  51. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    クライアント関数は、オーケス
    トレーター関数を起動するため
    に、Control Queueにメッセージ
    をプッシュします。
    Message

    View Slide

  52. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    Message
    オーケストレーター関数
    は、Control Queueのキュ
    ートリガーにより起動し
    ます。

    View Slide

  53. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    オーケストレーター関数が起動
    して、Plus2というアクティビテ
    ィ関数を実行します。

    View Slide

  54. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    アクティビティ関数
    オーケストレーター関数はHistory Tableに、オ
    ーケストレーター関数が起動したことを表す
    「ExecutionStarted」と「OrchestratorStarted」
    を記録します。前者は最初だけ、後者はリプ
    レイ開始のたびに記録されます。

    View Slide

  55. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    アクティビティ関数
    オーケストレーター関数はアクテ
    ィビティ関数を起動するために
    Work Item Queueにメッセージを
    プッシュします。
    Message

    View Slide

  56. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    アクティビティ関数
    オーケストレーター関数はHistory Tableに、アクテ
    ィビティ関数の起動予約したことを表す「
    TaskScheduled」と、リプレイが終わったことを表
    す「OrchestratorCompleted」を記録します。ここで
    一旦オーケストレーター関数は終了します。
    Message

    View Slide

  57. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    アクティビティ関数
    Message
    アクティビティ関数は、Work Item
    Queueのキュートリガーにより起動
    します。

    View Slide

  58. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    アクティビティ関数
    アクティビティ関数はHistory Tableに、タスクが完
    了したことを表す「TaskCompleted」を記録します
    。また、アクティビティ関数の結果をResultに記録
    します。

    View Slide

  59. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    Message
    アクティビティ関数はオーケスト
    レーター関数を起動するために
    Control Queueにメッセージをプッ
    シュします。

    View Slide

  60. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    Message
    オーケストレーター関数
    は、Control Queueのキュ
    ートリガーにより起動し
    ます。

    View Slide

  61. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    アクティビティ関数はHistory Tableに、リプレイが
    開始したことを表す「OrchestratorStarted」を記録
    します。

    View Slide

  62. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    アクティビティ関数Plus2を起動しようとしますが、History Table
    には既に実行完了である記録があるため、実行をスキップして
    Resultに記録されている4という結果だけを返します。

    View Slide

  63. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    アクティビティ関数MultiplyBy2を起
    動するために、Work Item Queueに
    メッセージをプッシュします。
    Message

    View Slide

  64. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    オーケストレーター関数はHistory Tableに、アクテ
    ィビティ関数の起動予約したことを表す「
    TaskScheduled」と、リプレイが終わったことを表
    す「OrchestratorCompleted」を記録します。ここで
    一旦オーケストレーター関数は終了します。
    Message

    View Slide

  65. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    Message
    アクティビティ関数は、Work Item
    Queueのキュートリガーにより起動
    します。

    View Slide

  66. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    TaskCompleted 8
    アクティビティ関数はHistory Tableに、タスクが完
    了したことを表す「TaskCompleted」を記録します
    。また、アクティビティ関数の結果をResultに記録
    します。

    View Slide

  67. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    TaskCompleted 8
    Message
    アクティビティ関数はオーケスト
    レーター関数を起動するために
    Control Queueにメッセージをプッ
    シュします。

    View Slide

  68. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    TaskCompleted 8
    Message
    オーケストレーター関数
    は、Control Queueのキュ
    ートリガーにより起動し
    ます。

    View Slide

  69. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    TaskCompleted 8
    アクティビティ関数Plus2を起動しようとしますが、History Table
    には既に実行完了である記録があるため、実行をスキップして
    Resultに記録されている4という結果だけを返します。

    View Slide

  70. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    TaskCompleted 8
    アクティビティ関数MultiplyBy2を起動しようとしますが、
    History Tableには既に実行完了である記録があるため、実行をス
    キップしてResultに記録されている8という結果だけを返します

    View Slide

  71. オーケストレーター
    関数
    int result1 = await context.CallActivityAsync("Plus2", num);
    int result2 = await context.CallActivityAsync("MultiplyBy2", result1);
    Control Queue
    クライアント関数
    Work Item Queue
    DurableFunctions
    HubHistory
    アクティビティ関数
    EventType Name Input Result
    ExecutionStarted Orchastrator 2
    OrchestratorStarted
    TaskScheduled Plus2
    OrchestratorCompleted
    TaskCompleted 4
    OrchestratorStarted
    TaskScheduled MultiplyBy2
    OrchestratorCompleted
    TaskCompleted 8
    ExecutionCompleted
    オーケストレーター関数は、実行が終了したこと
    を表す「ExecutionCompleted」を記録し、終わりま
    す。。。

    View Slide

  72. 技術ブログ「SIOS Tech.Lab」
    多分わかりやすいDurable Functions
    https://tech-lab.sios.jp/archives/12991

    View Slide

  73. SIOS Tech.Lab
    https://tech-lab.sios.jp/
    世界⼀わかりみの深い
    クラウドネイティブ
    on Azure
    https://youtube.com/playlist?list=PLbTt_DSTMYgGLUtZ0ewuBwhTBSZnNE2-w
    様々なメティアで情報発信しています!!
    技術ブログ
    YouTube配信

    View Slide