Durable Functions 中的函数链 - Hello 序列示例Function chaining in Durable Functions - Hello sequence sample

函数链是指以特定顺序执行一系列函数的模式。Function chaining refers to the pattern of executing a sequence of functions in a particular order. 通常需要将一个函数的输出应用于另一函数的输入。Often the output of one function needs to be applied to the input of another function. 本文介绍在完成 Durable Functions 快速入门(C#JavaScript)时创建的链接序列。This article describes the chaining sequence that you create when you complete the Durable Functions quickstart (C# or JavaScript). 有关 Durable Functions 的详细信息,请参阅 Durable Functions 概述For more information about Durable Functions, see Durable Functions overview.

先决条件Prerequisites

函数The functions

本文介绍示例应用中的以下函数:This article explains the following functions in the sample app:

  • E1_HelloSequence:在一个序列中多次调用 E1_SayHello 的一个业务流程协调程序函数E1_HelloSequence: An orchestrator function that calls E1_SayHello multiple times in a sequence. 它存储来自 E1_SayHello 调用的输出并记录结果。It stores the outputs from the E1_SayHello calls and records the results.
  • E1_SayHello:在字符串前添加“Hello”的一个活动函数E1_SayHello: An activity function that prepends a string with "Hello".
  • HttpStart:用于启动业务流程协调程序实例的一个 HTTP 触发的函数。HttpStart: An HTTP triggered function that starts an instance of the orchestrator.

E1_HelloSequence 业务流程协调程序函数E1_HelloSequence orchestrator function

        [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# orchestration 函数都必须具有 DurableOrchestrationContext 类型的参数,此参数存在于 Microsoft.Azure.WebJobs.Extensions.DurableTask 程序集中。All C# orchestration functions must have a parameter of type DurableOrchestrationContext, which exists in the Microsoft.Azure.WebJobs.Extensions.DurableTask assembly. 借助此上下文对象,可使用其 CallActivityAsync 方法调用其他活动 函数并传递输入参数。This context object lets you call other activity functions and pass input parameters using its CallActivityAsync method.

代码将在具有不同参数值的序列中调用三次 E1_SayHelloThe code calls E1_SayHello three times in sequence with different parameter values. 每个调用的返回值都会添加到 outputs 列表,函数末尾会返回该列表。The return value of each call is added to the outputs list, which is returned at the end of the function.

E1_SayHello 活动函数E1_SayHello activity function

        [FunctionName("E1_SayHello")]
        public static string SayHello([ActivityTrigger] IDurableActivityContext context)
        {
            string name = context.GetInput<string>();
            return $"Hello {name}!";
        }

活动使用了 ActivityTrigger 属性。Activities use the ActivityTrigger attribute. 使用提供的 IDurableActivityContext 执行活动相关操作,例如,使用 GetInput<T> 访问输入值。Use the provided IDurableActivityContext to perform activity related actions, such as accessing the input value using GetInput<T>.

E1_SayHello 的实现是一种相对简单的字符串格式设置操作。The implementation of E1_SayHello is a relatively trivial string formatting operation.

可以直接绑定到传递给活动函数的类型,而非绑定到 IDurableActivityContextInstead of binding to an IDurableActivityContext, you can bind directly to the type that is passed into the activity function. 例如:For example:

        [FunctionName("E1_SayHello_DirectInput")]
        public static string SayHelloDirectInput([ActivityTrigger] string name)
        {
            return $"Hello {name}!";
        }

HttpStart 客户端函数HttpStart client function

可以使用客户端函数启动业务流程协调程序函数的实例。You can start an instance of orchestrator function using a client function. 你将使用 HTTP 触发的函数 HttpStart 启动 E1_HelloSequence 的实例。You will use the HttpStart HTTP triggered function to start instances of E1_HelloSequence.

    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);
        }
    }

若要与业务流程协调程序进行交互,函数必须包含 DurableClient 输入绑定。To interact with orchestrators, the function must include a DurableClient input binding. 你使用客户端来启动业务流程。You use the client to start an orchestration. 它还可以帮助你返回 HTTP 响应,并在其中包含用于检查新业务流程状态的 URL。It can also help you return an HTTP response containing URLs for checking the status of the new orchestration.

运行示例Run the sample

若要执行 E1_HelloSequence 业务流程,请将以下 HTTP POST 请求发送到 HttpStart 函数。To execute the E1_HelloSequence orchestration, send the following HTTP POST request to the HttpStart function.

POST http://{host}/orchestrators/E1_HelloSequence

备注

前面的 HTTP 代码片段假定 host.json 文件中有一个条目,该条目从所有 HTTP 触发器函数 URL 中删除默认的 api/ 前缀。The previous HTTP snippet assumes there is an entry in the host.json file which removes the default api/ prefix from all HTTP trigger functions URLs. 可以在示例的 host.json 文件中找到此配置的标记。You can find the markup for this configuration in the host.json file in the samples.

例如,如果在名为“myfunctionapp”的函数应用中运行示例,请将“{host}”替换为“myfunctionapp.chinacloudsites.cn”。For example, if you're running the sample in a function app named "myfunctionapp", replace "{host}" with "myfunctionapp.chinacloudsites.cn".

结果为 HTTP 202 响应,如下所示(已简化):The result is an HTTP 202 response, like this (trimmed for brevity):

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...)

此时,业务流程已进行排队,并将立即开始运行。At this point, the orchestration is queued up and begins to run immediately. Location 标头中的 URL可用于检查执行的状态。The URL in the Location header can be used to check the status of the execution.

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

结果为业务流程的状态。The result is the status of the orchestration. 它运行和完成的速度很快,因此处于已完成 状态,并伴有如下所示响应(已简化):It runs and completes quickly, so you see it in the Completed state with a response that looks like this (trimmed for brevity):

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"}

可以看到,实例的 runtimeStatus 为已完成 ,且 output 包含 orchestrator 函数执行的 JSON 序列化结果。As you can see, the runtimeStatus of the instance is Completed and the output contains the JSON-serialized result of the orchestrator function execution.

备注

可对其他触发器类型(如 queueTriggereventHubTriggertimerTrigger)实施类似的启动器逻辑。You can implement similar starter logic for other trigger types, like queueTrigger, eventHubTrigger, or timerTrigger.

查看函数执行日志。Look at the function execution logs. 由于业务流程可靠性主题中所述的重播行为,E1_HelloSequence 函数已多次启动和完成。The E1_HelloSequence function started and completed multiple times due to the replay behavior described in the orchestration reliability topic. 另一方面,由于未重播这些函数执行,因此只执行三次 E1_SayHelloOn the other hand, there were only three executions of E1_SayHello since those function executions do not get replayed.

后续步骤Next steps

此示例演示了简单的函数链业务流程。This sample has demonstrated a simple function-chaining orchestration. 下一示例演示如何实现扇出/扇入模式。The next sample shows how to implement the fan-out/fan-in pattern.