関数チェーンは、一連のアクティビティを順番に実行するパターンです。 1 つのアクティビティの出力を次のアクティビティの入力に渡すのが一般的です。 この記事では、.NET、JavaScript、Python、Java用の Durable Task SDK のチェーン シーケンスについて説明します。
Functions
この記事では、サンプル アプリのこれらの関数について説明します。
- : を順番に複数回呼び出すオーケストレーター関数。 各出力が格納され、結果が記録されます。
- : 文字列の先頭に "Hello" を追加する アクティビティ関数 。
- : オーケストレーターのインスタンスを開始する HTTP によってトリガーされる 永続的クライアント 関数。
この記事では、サンプル アプリのこれらのコンポーネントについて説明します。
- 、 、 、または : 複数のアクティビティを順番に呼び出すオーケストレーター。 各出力が格納され、結果が記録されます。
- アクティビティ関数: 入力を処理し、結果を返すアクティビティ。 各アクティビティは、入力に対して単純な変換を実行します。
- クライアント: オーケストレーターのインスタンスを開始し、結果を待機するクライアント アプリ。
Orchestrator
[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var outputs = new List<string>();
outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return outputs;
}
すべての C# オーケストレーション関数には、DurableOrchestrationContext アセンブリに存在する Microsoft.Azure.WebJobs.Extensions.DurableTask 型のパラメーターが必要です。 このコンテキスト オブジェクトでは、他のアクティビティ関数を呼び出し、その メソッドを使用して入力パラメーターを渡すことができます。
このコードでは、 を異なるパラメーター値で 3 回続けて呼び出します。 各呼び出しの戻り値が 一覧に追加され、それが関数の末尾に返されます。
V3 プログラミング モデル
function.json
Visual Studio CodeまたはAzure ポータルで開発する場合は、オーケストレーター function.json ファイルを次に示します。
{
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
],
"disabled": false
}
キー設定は、 バインドの種類です。 すべての orchestrator 機能は、このトリガーの種類を使用する必要があります。
警告
オーケストレーター関数の "I/O なし" 規則に従うには、 トリガー バインドで入力バインドまたは出力バインドを使用しないでください。 他の入力バインドまたは出力バインドが必要な場合は、オーケストレーターが呼び出す 関数でそれらを使用します。 詳細については、「 オーケストレーター関数のコード制約」を参照してください。
index.js
オーケストレーター関数をこちらに示します。
const df = require("durable-functions");
module.exports = df.orchestrator(function* (context) {
context.log("Starting chain sample");
const output = [];
output.push(yield context.df.callActivity("E1_SayHello", "Tokyo"));
output.push(yield context.df.callActivity("E1_SayHello", "Seattle"));
output.push(yield context.df.callActivity("E1_SayHello", "London"));
return output;
});
すべての JavaScript オーケストレーション関数に、 module モジュールが含まれている必要があります。 JavaScript でDurable Functionsを記述できるライブラリです。 オーケストレーター関数と他の JavaScript 関数の 3 つの主な違い:
- オーケストレーター関数はジェネレーター関数です。
- この関数は、 モジュールの メソッドの呼び出しにラップされます (ここでは )。
- 関数は同期です。 メソッドはを呼び出すので、関数は戻ります。
オブジェクトには、 永続的なオーケストレーション コンテキスト オブジェクトが含まれています。このオブジェクトを使用すると、他の アクティビティ 関数を呼び出し、その メソッドを使用して入力パラメーターを渡すことができます。 このコードは、異なるパラメータ値で 3 回連続して呼び出され、非同期アクティビティ関数の呼び出しが返されるまで待機する必要があります。 各呼び出しの戻り値が 配列に追加されます。これは、関数の末尾に返されます。
V4 プログラミング モデル
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.orchestration("helloSequence", function* (context) {
context.log("Starting chain sample");
const output = [];
output.push(yield context.df.callActivity(helloActivityName, "Tokyo"));
output.push(yield context.df.callActivity(helloActivityName, "Seattle"));
output.push(yield context.df.callActivity(helloActivityName, "Cairo"));
return output;
});
すべての JavaScript オーケストレーション関数に、 module モジュールが含まれている必要があります。 このモジュールを使用すると、JavaScript でDurable Functionsを記述できます。 V4 ノード プログラミング モデルを使用するには、の バージョンをインストールする必要があります。
オーケストレーター関数と他の JavaScript 関数の 2 つの主な違い:
- オーケストレーター関数はジェネレーター関数です。
- 関数は同期です。 この関数は戻ります。
オブジェクトには、 永続的なオーケストレーション コンテキスト オブジェクトが含まれています。このオブジェクトを使用すると、他の アクティビティ 関数を呼び出し、その メソッドを使用して入力パラメーターを渡すことができます。 このコードでは、異なるパラメーター値を使って3回順番に呼び出しを行い、非同期アクティビティ関数の呼び出しが完了して返されるのを待つように示しています。 各呼び出しの戻り値が 配列に追加されます。これは、関数の末尾に返されます。
注記
Python Durable Functionsは、Functions 3.0 ランタイムでのみ使用できます。
function.json
Visual Studio CodeまたはAzure ポータルを開発に使用する場合は、オーケストレーター関数の function.json ファイルの内容を次に示します。 ほとんどの orchestrator function.json ファイルは、このような内容です。
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "context",
"type": "orchestrationTrigger",
"direction": "in"
}
]
}
重要なのはバインドの種類です。 すべての orchestrator 機能は、このトリガーの種類を使用する必要があります。
警告
Orchestrator 機能の "I/O なし" の規則に従うには、 トリガー バインドを使用する場合に、入力または出力バインドを使用しないでください。 他の入力または出力バインドが必要な場合は、 関数のコンテキストで使用する必要があります。それらがオーケストレーターによって呼び出されます。 詳細については、「オーケストレーター関数コードの制約」の記事を参照してください。
__init__.py
オーケストレーター関数をこちらに示します。
import azure.functions as func
import azure.durable_functions as df
def orchestrator_function(context: df.DurableOrchestrationContext):
result1 = yield context.call_activity('E1_SayHello', "Tokyo")
result2 = yield context.call_activity('E1_SayHello', "Seattle")
result3 = yield context.call_activity('E1_SayHello', "London")
return [result1, result2, result3]
main = df.Orchestrator.create(orchestrator_function)
すべてのPythonオーケストレーション関数には、durable-functions パッケージを含める必要があります。 PythonでDurable Functionsを記述できるライブラリです。 オーケストレーター関数と他のPython関数の 2 つの主な違い:
- オーケストレーター関数はジェネレーター関数です。
- ファイルの末尾に記述することで、オーケストレーター関数を登録します。 これは、ファイルで宣言されている他のヘルパー関数と区別するのに役立ちます。
オブジェクトでは、他の "アクティビティ" 関数を呼び出し、その メソッドを使用して入力パラメーターを渡すことができます。 このコードでは、異なるパラメーター値で順に3回呼び出します。そして、「await」を用いて実行が非同期アクティビティ関数呼び出しの完了を待つことを示します。 各呼び出しの戻り値は関数の末尾に返されます。
PowerShell サンプルはまだ使用できません。
このコードは、3 つのアクティビティを順番に呼び出し、各出力を次のアクティビティに渡すオーケストレーターを示しています。
using Microsoft.DurableTask;
[DurableTask]
public class GreetingOrchestration : TaskOrchestrator<string, string>
{
public override async Task<string> RunAsync(TaskOrchestrationContext context, string name)
{
// Step 1: Say hello to the person
string greeting = await context.CallActivityAsync<string>(nameof(SayHelloActivity), name);
// Step 2: Process the greeting
string processedGreeting = await context.CallActivityAsync<string>(nameof(ProcessGreetingActivity), greeting);
// Step 3: Finalize the response
string finalResponse = await context.CallActivityAsync<string>(nameof(FinalizeResponseActivity), processedGreeting);
return finalResponse;
}
}
すべての.NET オーケストレーターは、TaskOrchestrator<TInput, TOutput> から継承します。 では、を使用してアクティビティを呼び出すことができます。 このコードでは、3 つのアクティビティが順番に呼び出され、各アクティビティが前のアクティビティの出力を受け取ります。
次のコードは、3 つのアクティビティを順番に呼び出すオーケストレーターを示しています。
import {
OrchestrationContext,
TOrchestrator,
} from "@microsoft/durabletask-js";
const greetingOrchestrator: TOrchestrator = async function* (
ctx: OrchestrationContext,
name: string
): any {
// Step 1: Say hello to the person
const greeting: string = yield ctx.callActivity(sayHello, name);
// Step 2: Process the greeting
const processedGreeting: string = yield ctx.callActivity(processGreeting, greeting);
// Step 3: Finalize the response
const finalResponse: string = yield ctx.callActivity(finalizeResponse, processedGreeting);
return finalResponse;
};
すべての JavaScript オーケストレーターは、を使用してアクティビティを呼び出すジェネレーター関数 () です。 オーケストレーション コンテキストの メソッドは、アクティビティの実行をスケジュールします。 このコードは 3 つのアクティビティを順番に呼び出し、各アクティビティの出力を次のアクティビティに渡します。
次のコードは、3 つのアクティビティを順番に呼び出すオーケストレーターを示しています。
from durabletask import task
# Orchestrator function
def function_chaining_orchestrator(ctx: task.OrchestrationContext, name: str) -> str:
"""Orchestrator that demonstrates function chaining pattern."""
# Call first activity
greeting = yield ctx.call_activity(say_hello, input=name)
# Call second activity with the result from first activity
processed_greeting = yield ctx.call_activity(process_greeting, input=greeting)
# Call third activity with the result from second activity
final_response = yield ctx.call_activity(finalize_response, input=processed_greeting)
return final_response
すべてのPython オーケストレーターは、アクティビティを呼び出すために yield を使用するジェネレーター関数です。 オーケストレーション コンテキストの メソッドは、アクティビティの実行をスケジュールします。 このコードは 3 つのアクティビティを順番に呼び出し、各アクティビティの出力を次のアクティビティに渡します。
このサンプルは、.NET、JavaScript、Java、およびPythonについて示されています。
次のコードは、3 つのアクティビティを順番に呼び出すオーケストレーターを示しています。
import com.microsoft.durabletask.*;
DurableTaskGrpcWorker worker = DurableTaskSchedulerWorkerExtensions.createWorkerBuilder(connectionString)
.addOrchestration(new TaskOrchestrationFactory() {
@Override
public String getName() { return "ActivityChaining"; }
@Override
public TaskOrchestration create() {
return ctx -> {
String input = ctx.getInput(String.class);
// Call activities in sequence, passing output from one to the next
String x = ctx.callActivity("Reverse", input, String.class).await();
String y = ctx.callActivity("Capitalize", x, String.class).await();
String z = ctx.callActivity("ReplaceWhitespace", y, String.class).await();
ctx.complete(z);
};
}
})
.build();
Javaでは、オーケストレーターは TaskOrchestrationFactory を使用して定義されます。 コンテキストの メソッドは、アクティビティの実行をスケジュールし、 結果を待機します。 このコードは 3 つのアクティビティを順番に呼び出し、各アクティビティの出力を次のアクティビティに渡します。
アクティビティ
[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
アクティビティは、 属性を使用します。 アクティビティアクションには、入力を読み取るために「.」を使用します。
あいさつ文字列をフォーマットします。
にバインドするのではなく、アクティビティ関数に渡された型に直接バインドします。 次に例を示します。
[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
return $"Hello {name}!";
}
V3 プログラミング モデル
E1_SayHello/function.json
アクティビティ関数のfunction.jsonファイルは、〇のそれに似ていますが、「〇バインドタイプ」の代わりに「〇バインドタイプ」を使用する点が異なります。
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
],
"disabled": false
}
注記
オーケストレーション関数が呼び出すすべてのアクティビティ関数に対して、 バインドを使用します。
の実装は、比較的単純な文字列の書式設定操作です。
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
オーケストレーション関数とは異なり、アクティビティ関数には特別なセットアップは必要ありません。 オーケストレーターは、 バインディングの名前 (この場合は ) の下の オブジェクトに入力を渡します。 サンプルと同様に、エクスポートされた関数のパラメーターとしてバインド名を直接アクセスするように設定します。
V4 プログラミング モデル
あいさつ文字列を書式設定します。
const df = require("durable-functions");
const helloActivityName = "sayHello";
df.app.activity(helloActivityName, {
handler: function (input) {
return `Hello ${input}`;
},
});
オーケストレーション関数とは異なり、アクティビティ関数には特別なセットアップは必要ありません。 オーケストレーターは、入力を最初の引数として関数に渡します。 2 番目の引数は呼び出しコンテキストであり、この例では使用しません。
E1_SayHello/function.json
アクティビティ関数のための function.json ファイルは、〇〇のバインドの種類を代わりに使用する点を除いて、〇〇と似ています。
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
]
}
注記
オーケストレーション関数によって呼び出されるすべてのアクティビティ関数は、 バインドを使用する必要があります。
の実装は、比較的単純な文字列の書式設定操作です。
E1_SayHello/__init__.py
def main(name: str) -> str:
return f"Hello {name}!"
オーケストレーター関数とは異なり、アクティビティ関数には特別な設定は不要です。 オーケストレーター関数によって渡された入力には、関数のパラメーターとして直接アクセスできます。
PowerShell サンプルは近日公開予定です。
Durable Task SDK のアクティビティは、 から継承されます。
using Microsoft.DurableTask;
using Microsoft.Extensions.Logging;
[DurableTask]
public class SayHelloActivity : TaskActivity<string, string>
{
private readonly ILogger<SayHelloActivity> _logger;
public SayHelloActivity(ILogger<SayHelloActivity> logger)
{
_logger = logger;
}
public override Task<string> RunAsync(TaskActivityContext context, string name)
{
_logger.LogInformation("Activity SayHello called with name: {Name}", name);
return Task.FromResult($"Hello {name}!");
}
}
[DurableTask]
public class ProcessGreetingActivity : TaskActivity<string, string>
{
public override Task<string> RunAsync(TaskActivityContext context, string greeting)
{
return Task.FromResult($"{greeting} How are you today?");
}
}
[DurableTask]
public class FinalizeResponseActivity : TaskActivity<string, string>
{
public override Task<string> RunAsync(TaskActivityContext context, string response)
{
return Task.FromResult($"{response} I hope you're doing well!");
}
}
依存関係の挿入を使用して、 などのサービスを取得します。 属性を追加して、アクティビティをワーカーに登録します。
Durable Task SDK のアクティビティは単純な関数です。
import { ActivityContext } from "@microsoft/durabletask-js";
const sayHello = async (_ctx: ActivityContext, name: string): Promise<string> => {
return `Hello ${name}!`;
};
const processGreeting = async (_ctx: ActivityContext, greeting: string): Promise<string> => {
return `${greeting} How are you today?`;
};
const finalizeResponse = async (_ctx: ActivityContext, response: string): Promise<string> => {
return `${response} I hope you're doing well!`;
};
オーケストレーターとは異なり、アクティビティは HTTP 呼び出し、データベース クエリ、ファイル アクセスなどの I/O 操作を実行できます。 入力はパラメーターとして直接渡されます。
Durable Task SDK のアクティビティは単純な関数です。
from durabletask import task
def say_hello(ctx: task.ActivityContext, name: str) -> str:
"""First activity that greets the user."""
return f"Hello {name}!"
def process_greeting(ctx: task.ActivityContext, greeting: str) -> str:
"""Second activity that processes the greeting."""
return f"{greeting} How are you today?"
def finalize_response(ctx: task.ActivityContext, response: str) -> str:
"""Third activity that finalizes the response."""
return f"{response} I hope you're doing well!"
オーケストレーターとは異なり、アクティビティは HTTP 呼び出し、データベース クエリ、ファイル アクセスなどの I/O 操作を実行できます。 入力はパラメーターとして直接渡されます。
このサンプルは、.NET、JavaScript、Java、およびPythonについて示されています。
Javaのアクティビティは、TaskActivityFactory を使用して定義されます。
import com.microsoft.durabletask.*;
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "Reverse"; }
@Override
public TaskActivity create() {
return ctx -> {
String input = ctx.getInput(String.class);
StringBuilder builder = new StringBuilder(input);
builder.reverse();
return builder.toString();
};
}
})
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "Capitalize"; }
@Override
public TaskActivity create() {
return ctx -> ctx.getInput(String.class).toUpperCase();
}
})
.addActivity(new TaskActivityFactory() {
@Override
public String getName() { return "ReplaceWhitespace"; }
@Override
public TaskActivity create() {
return ctx -> {
String input = ctx.getInput(String.class);
return input.trim().replaceAll("\\s", "-");
};
}
})
を使用して、各アクティビティをワーカー ビルダーに登録します。 アクティビティは I/O 操作を実行し、オーケストレーターに結果を返すことができます。
Client
クライアント関数からオーケストレーター関数インスタンスを開始します。 HTTP によってトリガーされる関数を使用して、のインスタンスを開始します。
public static class HttpStart
{
[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
[DurableClient] IDurableClient starter,
string functionName,
ILogger log)
{
// Function input comes from the request content.
object eventData = await req.Content.ReadAsAsync<object>();
string instanceId = await starter.StartNewAsync(functionName, eventData);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
オーケストレーターと対話するには、 入力バインドを追加します。 クライアントを使用してオーケストレーションを開始し、URL を含む HTTP 応答を返して、新しいオーケストレーションの状態を確認します。
V3 プログラミング モデル
HttpStart/function.json
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": ["post"]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "orchestrationClient",
"direction": "in"
}
],
"disabled": false
}
オーケストレーターと対話するには、 入力バインドを追加します。
HttpStart/index.js
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);
};
を使用して、 オブジェクトを取得します。 クライアントを使用してオーケストレーションを開始し、URL を含む HTTP 応答を返して、新しいオーケストレーションの状態を確認します。
V4 プログラミング モデル
const df = require("durable-functions");
const { app } = require("@azure/functions");
app.http("httpStart", {
route: "orchestrators/{orchestratorName}",
extraInputs: [df.input.durableClient()],
handler: async (request, context) => {
const client = df.getClient(context);
const body = await request.json();
const instanceId = await client.startNew(request.params.orchestratorName, { input: body });
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(request, instanceId);
},
});
オーケストレーターを管理および操作するには、 入力バインドを追加します。 関数を登録するときに、 引数にバインドを指定します。 関数を呼び出して、入力を取得します。
を使用して、 オブジェクトを取得します。 クライアントを使用してオーケストレーションを開始し、URL を含む HTTP 応答を返して、新しいオーケストレーションの状態を確認します。
HttpStart/function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": [
"post",
"get"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
]
}
オーケストレーター操作をするには、関数に 入力バインドが含まれている必要があります。
HttpStart/__init__.py
import logging
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instance_id = await client.start_new(req.route_params["functionName"], None, None)
logging.info(f"Started orchestration with ID = '{instance_id}'.")
return client.create_check_status_response(req, instance_id)
DurableOrchestrationClient コンストラクターを使用して、Durable Functions クライアントを作成します。 クライアントを使用してオーケストレーションを開始し、URL を含む HTTP 応答を返して、新しいオーケストレーションの状態を確認します。
PowerShell サンプルは近日公開予定です。
クライアント アプリケーションからオーケストレーションを開始します。 クライアントはオーケストレーションをスケジュールし、完了を待つことができます。
using Microsoft.DurableTask.Client;
// Create the client
var client = DurableTaskClientBuilder.UseDurableTaskScheduler(connectionString).Build();
// Schedule a new orchestration instance
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(GreetingOrchestration),
input: "World");
Console.WriteLine($"Started orchestration with ID: {instanceId}");
// Wait for the orchestration to complete
OrchestrationMetadata result = await client.WaitForInstanceCompletionAsync(
instanceId,
getInputsAndOutputs: true);
Console.WriteLine($"Orchestration completed with result: {result.ReadOutputAs<string>()}");
Durable Task Scheduler への接続文字列を使用して、DurableTaskClientを作成します。 を使用してオーケストレーションを開始し、完了を待つします。
import {
DurableTaskAzureManagedClientBuilder,
} from "@microsoft/durabletask-js-azuremanaged";
const connectionString =
process.env.DURABLE_TASK_SCHEDULER_CONNECTION_STRING ||
"Endpoint=http://localhost:8080;Authentication=None;TaskHub=default";
const client = new DurableTaskAzureManagedClientBuilder()
.connectionString(connectionString)
.build();
// Schedule a new orchestration instance
const instanceId = await client.scheduleNewOrchestration(greetingOrchestrator, "World");
console.log(`Started orchestration with ID: ${instanceId}`);
// Wait for the orchestration to complete
const state = await client.waitForOrchestrationCompletion(instanceId, true, 30);
console.log(`Orchestration completed with result: ${state?.serializedOutput}`);
Durable Task Scheduler への接続文字列を使用して、DurableTaskAzureManagedClientBuilderを作成します。 を使用してオーケストレーションを開始し、完了を待つします。
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
# Create the client
client = DurableTaskSchedulerClient(
host_address=endpoint,
secure_channel=endpoint != "http://localhost:8080",
taskhub=taskhub_name,
token_credential=credential
)
# Schedule a new orchestration instance
instance_id = client.schedule_new_orchestration(
function_chaining_orchestrator,
input="World"
)
print(f"Started orchestration with ID: {instance_id}")
# Wait for the orchestration to complete
result = client.wait_for_orchestration_completion(instance_id, timeout=60)
if result and result.runtime_status == OrchestrationStatus.COMPLETED:
print(f"Orchestration completed with result: {result.serialized_output}")
その装置は Durable Task Scheduler に接続します。 を使用してオーケストレーションを開始し、完了を待つします。
このサンプルは、.NET、JavaScript、Java、およびPythonについて示されています。
import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azuremanaged.DurableTaskSchedulerClientExtensions;
// Create the client
DurableTaskClient client = DurableTaskSchedulerClientExtensions
.createClientBuilder(connectionString)
.build();
// Schedule a new orchestration instance
String instanceId = client.scheduleNewOrchestrationInstance(
"ActivityChaining",
new NewOrchestrationInstanceOptions().setInput("Hello, world!"));
System.out.println("Started orchestration with ID: " + instanceId);
// Wait for the orchestration to complete
OrchestrationMetadata result = client.waitForInstanceCompletion(
instanceId,
Duration.ofSeconds(30),
true);
System.out.println("Orchestration completed with result: " + result.readOutputAs(String.class));
接続文字列を使用して、DurableTaskClientを作成します。 を使用してオーケストレーションを開始し、完了を待つします。
サンプルを実行する
オーケストレーションを実行するには、この HTTP POST 要求を関数に送信します。
POST http://{host}/orchestrators/E1_HelloSequence
注記
前の HTTP スニペットは、サンプルの host.json ファイルが既定の プレフィックスをすべての HTTP トリガー関数 URL から削除することを前提としています。 サンプルのhost.jsonファイルでこの構成 を 見つけます。
たとえば、 という名前の関数アプリでサンプルを実行している場合は、 を に置き換えます。
要求は HTTP 202 を返します (簡潔にするためにトリミングされます)。
HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
(...trimmed...)
オーケストレーションはキューに入り、すぐに実行を開始します。 実行状態を確認するには、 ヘッダーの URL を使用します。
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
応答には、オーケストレーションの状態が表示されます。 インスタンスは迅速に完了するため、多くの場合、 完了 状態になり、次のような応答が返されます (簡潔にするためにトリミングされます)。
HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8
{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}
インスタンス は Completed で、 にはオーケストレーター関数の実行の JSON シリアル化された結果が含まれます。
注記
、、など、他のトリガーの種類に対して同様のスターター ロジックを実装します。
関数の実行ログを確認します。 関数は、オーケストレーションの信頼性で説明されている再生動作のために、複数回起動して完了します。 しかし、アクティビティ関数の実行は再生されないため、プログラムは3回しか実行されません。
サンプルを実行するには、次のものが必要です。
Durable Task Scheduler エミュレーターを起動 します (ローカル開発用)。
docker run -d -p 8080:8080 -p 8082:8082 --name dts-emulator mcr.microsoft.com/dts/dts-emulator:latest
ワーカーを起動 してオーケストレーターとアクティビティを登録します。
クライアントを実行 してオーケストレーションをスケジュールし、結果を待ちます。
クライアント出力には、チェーンされたオーケストレーションの結果が表示されます。
Started orchestration with ID: abc123
Orchestration completed with result: "Hello World! How are you today? I hope you're doing well!"
ワーカー ログには、各アクティビティが順番に実行され、その出力が次のアクティビティに渡されます。
次のステップ
このサンプルでは、単純な関数の連鎖によるオーケストレーションを示します。 次に、ファンアウト/ファンイン パターンを実装します。
このサンプルでは、単純な関数チェーン オーケストレーションを示します。 次に、その他のパターンを調べる。
JavaScript SDK の完全な例については、 Durable Task JavaScript SDK のサンプルを参照してください。