持久函数可以有多个触发器吗?
Can durable functions have multiple triggers?
我有一个每天由定时器触发器触发一次的持久函数:
[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
}
这很好用。出于测试目的,我还希望能够通过 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");
}
运行这些在本地,包括http trigger或者timer trigger都会触发该函数,但是在class中同时包含这两种触发事件都不会发生。是否可以让多个触发器类型启动一个编排触发器?
我相信每个函数只能有一个触发器类型,但可以建议您将所有逻辑写到一个单独的 project/assembly 中,然后只引用程序集并通过参数调用入口点,保留您的函数实现简洁明了,并将执行逻辑集中在另一个项目中(或 类 在同一项目中)。
在您的代码中,您应该具有 Orchestrator 和 Activity 函数,因此您可以编写一个 Activity 函数来完成工作并从两个 orchestrator 调用它。 Durable Functions 的指导是让编排器保持干净和简单的管理 - 编排,将工作卸载到活动。
我建议您查看 durable monitor pattern for your timer based requirement and look at the HTTP APIs 的 HTTP 触发器。
您可以做的是创建多个普通函数,每个函数对应一种类型的触发器。预定触发器、http 触发器、blob 触发器或任何其他受支持的触发器。
在该函数中,您可以启动一个新的编排函数。该编排功能本身不需要触发器。您只需要 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);
}
我有一个每天由定时器触发器触发一次的持久函数:
[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
}
这很好用。出于测试目的,我还希望能够通过 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");
}
运行这些在本地,包括http trigger或者timer trigger都会触发该函数,但是在class中同时包含这两种触发事件都不会发生。是否可以让多个触发器类型启动一个编排触发器?
我相信每个函数只能有一个触发器类型,但可以建议您将所有逻辑写到一个单独的 project/assembly 中,然后只引用程序集并通过参数调用入口点,保留您的函数实现简洁明了,并将执行逻辑集中在另一个项目中(或 类 在同一项目中)。
在您的代码中,您应该具有 Orchestrator 和 Activity 函数,因此您可以编写一个 Activity 函数来完成工作并从两个 orchestrator 调用它。 Durable Functions 的指导是让编排器保持干净和简单的管理 - 编排,将工作卸载到活动。
我建议您查看 durable monitor pattern for your timer based requirement and look at the HTTP APIs 的 HTTP 触发器。
您可以做的是创建多个普通函数,每个函数对应一种类型的触发器。预定触发器、http 触发器、blob 触发器或任何其他受支持的触发器。
在该函数中,您可以启动一个新的编排函数。该编排功能本身不需要触发器。您只需要 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);
}