我有一个带有 HttpTrigger 的 Azure 函数。
我想立即返回 202 Accepted 给调用者,然后实际处理调用,这大约需要一秒钟。
有没有一些最佳实践方法可以做到这一点?
在返回呼叫之前我不想做任何事情,因此首先调用 EventGrid 或类似的方法是不可能的。
通过调用 EventGrid,我可以在 EventGrid 调用完成后立即返回,并且实际处理可以在订阅事件的另一个函数中进行。我不希望这样做,因为调用 EventGrid 需要时间,并且它有时会失败或花费比正常时间更长的时间。
通过将消息添加到队列,我可以完成与使用 EventGrid 相同的任务,并且它也具有与上述相同的问题。
我知道,通过在不等待的情况下调用函数内的方法,它将不会等待响应,我将能够立即返回。然而,我的测试表明这是非常不现实的,但是请告诉我您是否认为这是可行的方法以及原因。
我可以使用 Thread 和 ThreadStart 等手动进行此操作,我想如果需要的话我可能会这样做,但我问这个问题是为了寻找更好的解决方案。
Durable Functions 扩展可以帮助解决这个问题。
您可以通过 HTTP 启动编排,该编排将返回客户端可以轮询状态的状态 URL。
有一个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)
编辑:刚刚意识到它仍然在返回响应之前等待函数执行。
| 归档时间: |
|
| 查看次数: |
5092 次 |
| 最近记录: |