在 Azure Function 上的 HttpTrigger 中立即返回

Nie*_*nch 10 azure-functions

我有一个带有 HttpTrigger 的 Azure 函数。

我想立即返回 202 Accepted 给调用者,然后实际处理调用,这大约需要一秒钟。

有没有一些最佳实践方法可以做到这一点?

在返回呼叫之前我不想做任何事情,因此首先调用 EventGrid 或类似的方法是不可能的。

拒绝的选项

调用事件网格

通过调用 EventGrid,我可以在 EventGrid 调用完成后立即返回,并且实际处理可以在订阅事件的另一个函数中进行。我不希望这样做,因为调用 EventGrid 需要时间,并且它有时会失败或花费比正常时间更长的时间。

添加到队列

通过将消息添加到队列,我可以完成与使用 EventGrid 相同的任务,并且它也具有与上述相同的问题。

调用函数时不使用“await”

我知道,通过在不等待的情况下调用函数内的方法,它将不会等待响应,我将能够立即返回。然而,我的测试表明这是非常不现实的,但是请告诉我您是否认为这是可行的方法以及原因。

定制螺纹

我可以使用 Thread 和 ThreadStart 等手动进行此操作,我想如果需要的话我可能会这样做,但我问这个问题是为了寻找更好的解决方案。

Fin*_*yan 6

Durable Functions 扩展可以帮助解决这个问题。

您可以通过 HTTP 启动编排,该编排将返回客户端可以轮询状态的状态 URL。

  • 我认为这确实相当于同样的事情,尽管也许您不必编写代码来执行此操作。 (2认同)

Arn*_*erc 1

有一个FunctionInvocationFilterAttribute可能就是您正在寻找的。该属性仍处于预览状态,但工作正常。您可以创建自己的属性来实现它,并通过覆盖该方法来定义函数执行时要执行的操作OnExecutingAsync

像这样的东西:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Host;
using System.Threading;
using System.Linq;

namespace FunctionApp
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class ReturnResponseBeforeExecutionAttribute : FunctionInvocationFilterAttribute
    {
        public override Task OnExecutingAsync(FunctionExecutingContext executingContext, CancellationToken cancellationToken)
        {
            var request = executingContext.Arguments.Values.FirstOrDefault(argument => argument is HttpRequest) as HttpRequest;

            request.HttpContext.Response.StatusCode = 202;
            request.HttpContext.Response.Body.Flush();
            request.HttpContext.Response.Body.Close();
            return Task.CompletedTask;
        }
    }

    public class DoStuff
    {
        [ReturnResponseBeforeExecution]
        [FunctionName("DoStuff")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:刚刚意识到它仍然在返回响应之前等待函数执行。