不使用HttpTrigger的Azure持久函数调用(自动启动)

xxslljrj  于 2022-12-24  发布在  其他
关注(0)|答案(3)|浏览(154)

我正在查看这个示例,以便在设置超时后运行一个持久函数Activity。
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-eternal-orchestrations
这将允许我的函数活动执行数据处理,然后等待正好1个小时,然后再尝试加载。这将永远继续运行。完美。
但是,在将函数发布到Azure时,我不希望通过关联的HTTP触发器手动调用/启动函数,而只希望持久函数自动启动并开始处理。
这可能吗?如果不可能,建议的变通方案是什么?
谢谢!

busg9geu

busg9geu1#

正如在评论中所讨论的,一种方法是在您的发布管道中添加一个新的任务。
以下是我从您的问题中了解到的设置:

[FunctionName("ClientFunction")]
public static async Task<HttpResponseMessage> OnHttpTriggerAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post")]
            HttpRequestMessage request, [OrchestrationClient] DurableOrchestrationClient starter, ILogger logger)
{
    // Triggers the orchestrator.
    string instanceId = await starter.StartNewAsync("OrchestratorFunction", null);

    return new HttpResponseMessage(HttpStatusCode.OK);
}

[FunctionName("OrchestratorFunction")]
public static async Task DoOrchestrationThingsAsync([OrchestrationTrigger] DurableOrchestrationContext context, ILogger logger)
{
    DateTime deadline = context.CurrentUtcDateTime.Add(TimeSpan.FromHours(1));
    await context.CreateTimer(deadline, CancellationToken.None);

    // Triggers some yout activity.
    await context.CallActivityAsync("ActivityFunction", null);
}

[FunctionName("ActivityFunction")]
public static Task DoAnAwesomeActivity([ActivityTrigger] DurableActivityContext context)
{
}

现在,每次部署新版本的Function App时,都需要运行Orchestrator,但是,我不认为它可以自己启动。
我建议使用一个简单的bash脚本(使用curl或其他方法),在适当的URL调用ClientFunction

最重要的是,这个解决方案的一个好处是,如果Azure功能没有响应,您可以使部署失败。

mpgws1up

mpgws1up2#

这似乎也起作用了。

[FunctionName("AutoStart")]
public static async Task Run([TimerTrigger("*/5 * * * * *", RunOnStartup = true, UseMonitor = false)]TimerInfo myStartTimer, 
    [DurableClient] IDurableClient orchestrationClient, ILogger log)
    {
        string instanceId = await orchestrationClient.StartNewAsync("Start_Orchestrator", null);
    }
j9per5c4

j9per5c43#

我不知道这是否有隐藏的问题,但我现在正在试验一个TimerTrigger,它在启动时运行,也在每天午夜运行一次(或您想要的任何时间表),TimerTrigger将搜索示例列表,查找此业务流程的任何运行示例,终止它们,然后启动一个新的示例。

private const string MyOrchestrationName = "MyOrchestration";

[FunctionName("MyOrchestration_Trigger")]
public async Task MyOrchestrationr_Trigger(
    [TimerTrigger("0 0 0 * * *", RunOnStartup = true)] TimerInfo timer,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log,
    CancellationToken cancellationToken)
{
    // Get all the instances currently running that have a status of Pending, Running, ContinuedAsNew
    var instances = await starter.ListInstancesAsync(new OrchestrationStatusQueryCondition()
    {
        ShowInput = false,
        RuntimeStatus = new List<OrchestrationRuntimeStatus>() { OrchestrationRuntimeStatus.Suspended, OrchestrationRuntimeStatus.Pending, OrchestrationRuntimeStatus.Running, OrchestrationRuntimeStatus.ContinuedAsNew }
    }, cancellationToken);

    // Find any instances of the current orchestration that are running.
    var myInstances = instances.DurableOrchestrationState.Where(inst => inst.Name == MyOrchestrationName);
    List<Task> terminateTasks = new List<Task>();
    foreach (var instance in myInstances )
    {
        // Delete any instances that are currently running.
        terminateTasks.Add(starter.TerminateAsync(instance.InstanceId, $"Restarting eternal orchestration"));
    }
    await Task.WhenAll(terminateTasks);

    // Start the new task now that other instances have been terminated.
    string instanceId = await starter.StartNewAsync(MyOrchestrationName, null);

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

我认为至少对我的目的来说这是安全的。当你终止时正在运行的任何活动仍然会运行到完成(这是我在我的情况下想要的),所以你只需要杀死它并按计划重新启动它。

相关问题