在 ASP.NET 核心中处理长阻塞 API 调用

Handling long blocking API calls in ASP.NET Core

我正在构建一个 API 来处理立即执行大量工作的 http 调用。

例如,在一个控制器中,有一个动作(Post 请求)会在主体中获取数据,并执行一些应该立即完成的处理,但会持续大约 1 到 2分钟。

我正在使用 CQRS 和 Mediatr,在这个 post 请求中,我调用一个命令来处理处理。

考虑到这一点,我希望 post 请求启动命令,然后 return 向用户发出 Ok,尽管命令仍在后台 运行。一切完成后,将通过电子邮件通知用户。

有人知道完成此操作的最佳做​​法吗?

虽然我正在使用 MediatR,将请求发送到处理程序,但调用并未并行执行。

[HttpPost]
public async Task<IActionResult> RequestReports([FromBody] ReportsIntent reportsIntent)
{
     await _mediator.Send(new GetEndOfWeekReports.Command(companyId, clientId, reportsIntent));
     return Ok();
}

我会处理 API 需要一些时间的电话和可以直接完成的电话。

当我执行 API 需要时间的调用时,我会将它们排队并在后端处理它们。

一个典型的 API 调用看起来像这样:

POST http://api.example.com/orders HTTP/1.1
Host: api.example.com

HTTP/1.1 201 Created
Date: Fri, 5 Oct 2012 17:17:11 GMT
Content-Length: 123
Content-Type: application/json
Location: http://poll.example.com/orders/59cc233e-4068-4d4a-931d-cd5eb93f8c52.xml
ETag: "c180de84f951g8" 

{ uri: 'http://poll.example.com/orders/59cc233e-4068-4d4a-931d-cd5eb93f8c52.xml'}

返回的 URL 是唯一的 url,客户可以在其中 poll/query 了解作业的状态。

当客户端查询此 URL 时,它可能看起来像这样:

稍后完成时,结果将类似于:

其中数据url 是 link 到 result/report 客户端然后可以下载。

Does someone know any best practice to accomplish this?

Yes(如我的博客所述)。

您需要我所说的“基本分布式架构”。具体来说,您至少需要:

  1. 持久队列。 “持久”在这里的意思是“在磁盘上;而不是 in-memory”。
  2. 后端处理器。

因此网络 api 会将请求中的所有必要数据序列化为队列消息并将其放入队列,然后 return 发送给客户端。

然后后端处理器从该队列中检索工作并执行实际工作。在您的情况下,这项工作以发送电子邮件结束。

在某种程度上,这有点像 MediatR,但明确地使用 on-disk 队列和一个单独的进程作为您的处理程序退出进程。