在 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(如我的博客所述)。
您需要我所说的“基本分布式架构”。具体来说,您至少需要:
- 持久队列。 “持久”在这里的意思是“在磁盘上;而不是 in-memory”。
- 后端处理器。
因此网络 api 会将请求中的所有必要数据序列化为队列消息并将其放入队列,然后 return 发送给客户端。
然后后端处理器从该队列中检索工作并执行实际工作。在您的情况下,这项工作以发送电子邮件结束。
在某种程度上,这有点像 MediatR,但明确地使用 on-disk 队列和一个单独的进程作为您的处理程序退出进程。
我正在构建一个 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(如我的博客所述)。
您需要我所说的“基本分布式架构”。具体来说,您至少需要:
- 持久队列。 “持久”在这里的意思是“在磁盘上;而不是 in-memory”。
- 后端处理器。
因此网络 api 会将请求中的所有必要数据序列化为队列消息并将其放入队列,然后 return 发送给客户端。
然后后端处理器从该队列中检索工作并执行实际工作。在您的情况下,这项工作以发送电子邮件结束。
在某种程度上,这有点像 MediatR,但明确地使用 on-disk 队列和一个单独的进程作为您的处理程序退出进程。