简体   繁体   English

持久函数可以有多个触发器吗?

[英]Can durable functions have multiple triggers?

I have a durable function that is triggered once a day by a Timer Trigger:我有一个由定时器触发器每天触发一次的持久函数:

[FunctionName("MyDurableFunction")]
public static async Task Run(
    [TimerTrigger("0 0 23 * * *", RunOnStartup = false)] TimerInfo myTimer,
    [OrchestrationClient] DurableOrchestrationClient starter,
    ILogger log)
{
    await starter.StartNewAsync("OrchestrationFunction", null);
}

[FunctionName("OrchestrationFunction")]
public static async Task OrchestrationFunction(
    [OrchestrationTrigger]DurableOrchestrationContext context,
    ILogger log)
{
    // do stuff
}

This works fine.这工作正常。 For testing purposes I would also like to be able to trigger the durable function via a Http Trigger, so I added this:出于测试目的,我还希望能够通过 Http 触发器触发持久功能,因此我添加了以下内容:

[FunctionName("MyDurableFunctionHttpTrigger")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "demo")]HttpRequest req, 
    [OrchestrationClient] DurableOrchestrationClient starter, 
    ILogger log)
{
    await starter.StartNewAsync("OrchestrationFunction", null);
    return new OkObjectResult("blah");
}

Running these locally, including either the http trigger or the timer trigger will trigger the function, but including both in the class means that neither trigger events will occur.在本地运行这些,包括 http 触发器或计时器触发器将触发该函数,但在类中同时包含这两个触发器意味着不会发生触发事件。 Is it possible to have multiple trigger types start an orchestration trigger?是否可以让多个触发器类型启动一个编排触发器?

I believe you can only have one trigger type per function but can suggest you write all your logic in to a separate project/assembly and then just reference the assembly and call the entry point via parameters, keeping your function implementation clean and simple and centralising the execution logic in another project (or classes within the same project).我相信每个函数只能有一个触发器类型,但可以建议您将所有逻辑写入单独的项目/程序集,然后只引用程序集并通过参数调用入口点,保持函数实现干净简单,并集中另一个项目(或同一项目中的类)中的执行逻辑。

On your code, you should have Orchestrator and Activity functions, so you could write one Activity function to do the work and call it from two orchestrators.在您的代码中,您应该有 Orchestrator 和 Activity 函数,因此您可以编写一个 Activity 函数来完成这项工作,并从两个协调器中调用它。 The guidance on Durable Functions is to keep the orchestrator clean and simple managing just that - the orchestration, offloading the work to the Activities. Durable Functions 的指导是保持编排器干净和简单的管理 - 编排,将工作卸载到活动。

I recommend you look at the durable monitor pattern for your timer based requirement and look at the HTTP APIs for HTTP Triggers.我建议您查看基于计时器的需求的持久监视器模式,并查看 HTTP 触发器的HTTP API

What you could do is create multiple normal functions, one for each type of trigger.您可以做的是创建多个普通函数,每种类型的触发器一个。 A scheduled trigger, http trigger, blob trigger, or any other supported trigger.计划触发器、http 触发器、blob 触发器或任何其他受支持的触发器。

Within that function you can start a new orchestration function.在该函数中,您可以启动一个新的编排函数。 That orchestration function does not require a trigger in itself.该编排功能本身不需要触发器。 You only need the DurableOrchestrationContext.您只需要 DurableOrchestrationContext。

public static async Task<object> RunOrchestrator(
    [OrchestrationTrigger] DurableOrchestrationContext context,
    ILogger log)
{
    // orchestration logic here
}

[FunctionName("Info_HttpStart1")]
public static async Task<HttpResponseMessage> HttpStart(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "starter1")]HttpRequestMessage req,
    [OrchestrationClient]DurableOrchestrationClient starter,
    ILogger log)
{
    // Function input comes from the request content.
    string instanceId = await starter.StartNewAsync("Info", null);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

[FunctionName("Info_HttpStart2")]
public static async Task<HttpResponseMessage> HttpStart(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "starter2")]HttpRequestMessage req,
    [OrchestrationClient]DurableOrchestrationClient starter,
    ILogger log)
{
    // Function input comes from the request content.
    string instanceId = await starter.StartNewAsync("Info", null);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM