Durable Functions 中的函数链 - Hello 序列示例

函数链是指以特定顺序执行一系列函数的模式。 通常需要将一个函数的输出应用于另一函数的输入。 本文介绍在完成 Durable Functions 快速入门(C#JavaScriptTypeScriptPythonPowerShellJava)时创建的链接序列。 有关 Durable Functions 的详细信息,请参阅 Durable Functions 概述

先决条件

注意

适用于 Azure Functions 的 Node.js 编程模型版本 4 处于预览阶段。 新版 v4 模型旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 在升级指南中详细了解 v3 和 v4 之间的差异。

在以下代码片段中,JavaScript (PM4) 表示编程模型 V4,即新体验。

函数

本文介绍示例应用中的以下函数:

  • E1_HelloSequence:在一个序列中多次调用 E1_SayHello 的一个业务流程协调程序函数。 它存储来自 E1_SayHello 调用的输出并记录结果。
  • E1_SayHello:在字符串前添加“Hello”的一个活动函数
  • HttpStart:HTTP 触发的持久客户端函数,用于启动业务流程协调程序的实例。

E1_HelloSequence 业务流程协调程序函数

        [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 程序集中。 借助此上下文对象,可使用其 CallActivityAsync 方法调用其他活动 函数并传递输入参数。

代码将在具有不同参数值的序列中调用三次 E1_SayHello。 每个调用的返回值都会添加到 outputs 列表,函数末尾会返回该列表。

E1_SayHello 活动函数

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

活动使用了 ActivityTrigger 属性。 使用提供的 IDurableActivityContext 执行活动相关操作,例如,使用 GetInput<T> 访问输入值。

E1_SayHello 的实现是一种相对简单的字符串格式设置操作。

可以直接绑定到传递给活动函数的类型,而非绑定到 IDurableActivityContext。 例如:

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

HttpStart 客户端函数

可以使用客户端函数启动业务流程协调程序函数的实例。 你将使用 HTTP 触发的函数 HttpStart 启动 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 输入绑定。 你使用客户端来启动业务流程。 它还可以帮助你返回 HTTP 响应,并在其中包含用于检查新业务流程状态的 URL。

运行示例

若要执行 E1_HelloSequence 业务流程,请将以下 HTTP POST 请求发送到 HttpStart 函数。

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

注意

前面的 HTTP 代码片段假定 host.json 文件中有一个条目,该条目从所有 HTTP 触发器函数 URL 中删除默认的 api/ 前缀。 可以在示例的 host.json 文件中找到此配置的标记。

例如,如果在名为“myfunctionapp”的函数应用中运行示例,请将“{host}”替换为“myfunctionapp.chinacloudsites.cn”。

结果为 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...)

此时,业务流程已进行排队,并将立即开始运行。 Location 标头中的 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"}

可以看到,实例的 runtimeStatus 为已完成 ,且 output 包含 orchestrator 函数执行的 JSON 序列化结果。

注意

可对其他触发器类型(如 queueTriggereventHubTriggertimerTrigger)实施类似的启动器逻辑。

查看函数执行日志。 由于业务流程可靠性主题中所述的重播行为,E1_HelloSequence 函数已多次启动和完成。 另一方面,由于未重播这些函数执行,因此只执行三次 E1_SayHello

后续步骤

此示例演示了简单的函数链业务流程。 下一示例演示如何实现扇出/扇入模式。