次の方法で共有


オーケストレーションのバージョン管理 (プレビュー)

永続的オーケストレーション システムを使用する場合、オーケストレーションのアップグレードとダウングレードは重要な考慮事項です。 オーケストレーションが中断され、後で再開された場合 (ホストの更新中など)、Durable Task Scheduler はオーケストレーションのイベントを再生し、次の手順を実行する前に前のすべての手順が正常に実行されたことを確認します。 このアクションにより、持続性のある実行パラダイムの中心的な約束の 1 つである信頼性が保証されます。

展開間でオーケストレーションが変更された場合、実行される手順が同じでなくなる可能性があります。 この場合、システムはオーケストレーションの続行を許可するのではなく、NonDeterministicError をスローします。

オーケストレーションのバージョン管理 は、非決定的な問題を防ぎ、新しい (または古い) オーケストレーションをシームレスに操作できるようにします。 Durable Task Scheduler には 2 種類のバージョン管理スタイルがあり、個別に使用することも、一緒に使用することもできます。

Von Bedeutung

現時点では、Durable Task SDK は JavaScript と PowerShell では使用できません。

Von Bedeutung

現時点では、Durable Task SDK は JavaScript と PowerShell では使用できません。

クライアント/コンテキストベースの条件付きバージョン管理

オーケストレーションにバージョンを設定するには、最初にクライアントで設定する必要があります。

.NET SDK では、標準のホスト ビルダー拡張機能が使用されます。

v1.9.0 以降の .NET SDK (Microsoft.DurableTask.Client.AzureManaged) で使用できます。

builder.Services.AddDurableTaskClient(builder =>
{
    builder.UseDurableTaskScheduler(connectionString);
    builder.UseDefaultVersion("1.0.0");
});

v1.6.0 以降の Java SDK (com.microsoft:durabletask-client) で使用できます。

public DurableTaskClient durableTaskClient(DurableTaskProperties properties) {
    // Create client using Azure-managed extensions
    return DurableTaskSchedulerClientExtensions.createClientBuilder(properties.getConnectionString())
        .defaultVersion("1.0")
        .build();
}
 c = DurableTaskSchedulerClient(host_address=endpoint, secure_channel=secure_channel,
                                   taskhub=taskhub_name, token_credential=credential,
                                   default_version="1.0.0")

バージョンをクライアントに追加すると、このホストによって開始されたすべてのオーケストレーションでバージョン 1.0.0が使用されます。 バージョンは単純な文字列であり、任意の値を受け入れます。 ただし、SDK はこれを .NET の System.Version に変換しようとします。

  • 変換 できる 場合は、そのライブラリが比較に使用されます。
  • そうでない場合は、単純な文字列比較が使用されます。

クライアントでバージョンを指定すると、 TaskOrchestrationContextでも使用できるようになります。つまり、条件付きステートメントでバージョンを使用できます。 新しいオーケストレーション バージョンに適切なバージョンの制限がある限り、古いオーケストレーション バージョンと新しいオーケストレーション バージョンの両方を同じホスト上で一緒に実行できます。

Example:

[DurableTask]
class HelloCities : TaskOrchestrator<string, List<string>>
{
    private readonly string[] Cities = ["Seattle", "Amsterdam", "Hyderabad", "Kuala Lumpur", "Shanghai", "Tokyo"];

    public override async Task<List<string>> RunAsync(TaskOrchestrationContext context, string input)
    {
        List<string> results = [];
        foreach (var city in Cities)
        {
            results.Add(await context.CallSayHelloAsync($"{city} v{context.Version}"));
            if (context.CompareVersionTo("2.0.0") >= 0)
            {
                results.Add(await context.CallSayGoodbyeAsync($"{city} v{context.Version}"));
            }
        }

        Console.WriteLine("HelloCities orchestration completed.");
        return results;
    }
}

バージョンをクライアントに追加すると、このクライアントによって開始されたすべてのオーケストレーションでバージョン 1.0.0が使用されます。 バージョンは単純な文字列であり、任意の値を受け入れます。

クライアントでバージョンを指定すると、 TaskOrchestrationでも使用できるようになります。つまり、条件付きステートメントでバージョンを使用できます。 新しいオーケストレーション バージョンに適切なバージョンのゲーティングがある限り、古いオーケストレーション バージョンと新しいオーケストレーション バージョンの両方を同じクライアント上で一緒に実行できます。

Example:

public TaskOrchestration create() {
    return ctx -> {
        List<String> results = new ArrayList<>();
        for (String city : new String[]{ "Seattle", "Amsterdam", "Hyderabad", "Kuala Lumpur", "Shanghai", "Tokyo" }) {
            results.add(ctx.callActivity("SayHello", city, String.class).await());
            if (VersionUtils.compareVersions(ctx.getVersion(), "2.0.0") >= 0) {
                // Simulate a delay for newer versions
                results.add(ctx.callActivity("SayGoodbye", city, String.class).await());
            }
        }
        ctx.complete(results);
    };
}

バージョンをクライアントに追加すると、このクライアントによって開始されたすべてのオーケストレーションでバージョン 1.0.0が使用されます。 バージョンは、セマンティック バージョン管理の比較をサポートし、任意の値を受け入れる、 packaging.versionを使用して解析された単純な文字列です。

クライアントでバージョンを指定すると、 task.OrchestrationContextでも使用できるようになります。つまり、条件付きステートメントでバージョンを使用できます。 新しいオーケストレーション バージョンに適切なバージョンのゲーティングがある限り、古いオーケストレーション バージョンと新しいオーケストレーション バージョンの両方を同じクライアント上で一緒に実行できます。

Example:

def orchestrator(ctx: task.OrchestrationContext, _):
    if ctx.version == "1.0.0":
        # For version 1.0.0, we use the original logic
        result: int = yield ctx.call_activity(activity_v1, input="input for v1")
    elif ctx.version == "2.0.0":
        # For version 2.0.0, we use the updated logic
        result: int = yield ctx.call_activity(activity_v2, input="input for v2")
    else:
        raise ValueError(f"Unsupported version: {ctx.version}")
    return {
        'result': result,
    }

この例では、SayGoodbye オーケストレーションにHelloCities アクティビティを追加しました。 このアクティビティは、 2.0.0 以降のオーケストレーション バージョンに対してのみ呼び出されます。 単純な条件付きステートメントを使用すると、バージョンが 2.0.0 未満のオーケストレーションは引き続き機能し、新しいオーケストレーションには新しいアクティビティが含まれます。

クライアントのバージョン管理を使用する場合

クライアントのバージョン管理は、オーケストレーションのバージョン管理に最も簡単なメカニズムを提供しますが、バージョンとの対話はプログラミングを集中的に行う可能性があります。 次の場合は、クライアントのバージョン管理を使用します。

  • すべてのバージョンで標準バージョンが必要な場合、または
  • 特定のバージョンに関するカスタム ロジックが必要です。

ワーカーベースのバージョン管理

オーケストレーションにはバージョンを設定するためのクライアント バージョンが必要ですが、worker ベースのバージョン管理メソッドを使用すると、オーケストレーションでの条件付きを回避できます。 ワーカーは、実行を開始する前に、さまざまなバージョンのオーケストレーションに対してアクションを実行する方法を選択します。

ワーカーのバージョン管理では、次のフィールドを設定する必要があります。

  1. ワーカーのバージョン。

  2. ワーカーによって開始されたサブオーケストレーションに適用される既定のバージョン。

  3. ワーカーがオーケストレーションのバージョンと照合するために使用する戦略。

    名前 説明
    無し 作業の処理中にバージョンが考慮されない
    オーケストレーションとワーカーのバージョンが正確に一致している必要があります
    現在または旧バージョン オーケストレーションのバージョンが、ワーカーのバージョン以下である必要があります
  4. バージョンがマッチング戦略を満たしていない場合にワーカーがとる戦略。

    名前 説明
    リジェクト オーケストレーションは作業者によって拒否されますが、後で再度試行されるため作業キューに残ります。
    失敗 オーケストレーションが失敗し、作業キューから削除される

クライアントのバージョン管理と同様に、標準のホスト ビルダー パターンを使用してこれらのフィールドを設定できます。

v1.9.0 以降、.NET SDK (Microsoft.DurableTask.Worker.AzureManaged) で使用できます。

builder.Services.AddDurableTaskWorker(builder =>
{
    builder.AddTasks(r => r.AddAllGeneratedTasks());
    builder.UseDurableTaskScheduler(connectionString);
    builder.UseVersioning(new DurableTaskWorkerOptions.VersioningOptions
    {
        Version = "1.0.0",
        DefaultVersion = "1.0.0",
        MatchStrategy = DurableTaskWorkerOptions.VersionMatchStrategy.Strict,
        FailureStrategy = DurableTaskWorkerOptions.VersionFailureStrategy.Reject,
    });
});

v1.6.0 以降、Java SDK (com.microsoft:durabletask-client) で使用できます。

private static DurableTaskGrpcWorker createTaskHubServer() {
    DurableTaskGrpcWorkerBuilder builder = new DurableTaskGrpcWorkerBuilder();
    builder.useVersioning(new DurableTaskGrpcWorkerVersioningOptions(
            "1.0",
            "1.0",
            DurableTaskGrpcWorkerVersioningOptions.VersionMatchStrategy.CURRENTOROLDER,
            DurableTaskGrpcWorkerVersioningOptions.VersionFailureStrategy.REJECT));

    // Orchestrations can be defined inline as anonymous classes or as concrete classes
    builder.addOrchestration(new TaskOrchestrationFactory() {
        @Override
        public String getName() { return "HelloCities"; }

        @Override
        public TaskOrchestration create() {
            return ctx -> {
                List<String> results = new ArrayList<>();
                for (String city : new String[]{ "Seattle", "Amsterdam", "Hyderabad", "Kuala Lumpur", "Shanghai", "Tokyo" }) {
                    results.add(ctx.callActivity("SayHello", city, String.class).await());
                }
                ctx.complete(results);
            };
        }
    });

    // Activities can be defined inline as anonymous classes or as concrete classes
    builder.addActivity(new TaskActivityFactory() {
        @Override
        public String getName() { return "SayHello"; }

        @Override
        public TaskActivity create() {
            return ctx -> {
                String input = ctx.getInput(String.class);
                return "Hello, " + input + "!";
            };
        }
    });

    return builder.build();
}
with DurableTaskSchedulerWorker(host_address=endpoint, secure_channel=secure_channel,
                                taskhub=taskhub_name, token_credential=credential) as w:
    # This worker is versioned for v2, as the orchestrator code has already been updated
    # CURRENT_OR_OLDER allows this worker to process orchestrations versioned below 2.0.0 - e.g. 1.0.0
    w.use_versioning(worker.VersioningOptions(
        version="2.0.0",
        default_version="2.0.0",
        match_strategy=worker.VersionMatchStrategy.CURRENT_OR_OLDER,
        failure_strategy=worker.VersionFailureStrategy.FAIL
    ))
    w.add_orchestrator(orchestrator)
    w.add_activity(activity_v1)
    w.add_activity(activity_v2)
    w.start()

失敗戦略

拒否する

オーケストレーションで後に再試行するか、または別のワーカーで目的の動作がある場合は、Reject 失敗戦略を使用します。 Rejectエラー中:

  1. オーケストレーションが拒否され、作業キューに返されます。
  2. オーケストレーションがデキューされます。
  3. デキューされたオーケストレーションは、別のワーカーまたは同じワーカーに再び割り当てられる可能性があります。

このプロセスは、オーケストレーションを処理できるワーカーが使用可能になるまで繰り返されます。 この戦略は、オーケストレーションが更新されるデプロイをシームレスに処理します。 展開が進むにつれて、オーケストレーションを処理できないワーカーはオーケストレーションを拒否し、処理できるワーカーはオーケストレーションを処理します。

ワーカーとオーケストレーションバージョンを混在させる機能により、ブルーグリーンデプロイなどのシナリオが可能になります。

失敗

他のバージョンが想定されていない場合は、 Fail エラー戦略を使用します。 この場合、新しいバージョンは異常であり、ワーカーはそれに対して作業を試みる必要さえありません。 Durable Task Scheduler はオーケストレーションに失敗し、終了状態になります。

Worker のバージョン管理を使用する場合

不明またはサポートされていないオーケストレーション バージョンをまったく実行しないシナリオでは、ワーカーのバージョン管理を使用します。 worker にバージョン処理コードを配置する代わりに、ワーカーのバージョン管理によってオーケストレーションの実行が停止されます。 このメソッドを使用すると、オーケストレーション コードを簡単にできます。 コードを変更しなくても、ブルーグリーンデプロイなど、さまざまなデプロイ シナリオを処理できます。

次のステップ