【问题标题】:Background task in fastapi making blocking requestsfastapi中的后台任务发出阻塞请求
【发布时间】:2022-01-05 11:06:50
【问题描述】:

我有一个资源密集型异步方法,我想将它作为后台任务运行。它的示例代码如下所示:

@staticmethod
async def trigger_task(id: str, run_e2e: bool = False):
    try:
        add_status_for_task(id)
        result1, result2 = await task(id)
        update_status_for_task(id, result1, result2)
    except Exception:
        update_status_for_task(id, 'FAIL')


@router.post("/task")
async def trigger_task(background_tasks: BackgroundTasks):
    background_tasks.add_task(EventsTrigger.trigger_task)
    return {'msg': 'Task submitted!'}

当我触发这个端点时,我期望一个即时输出:{'msg': 'Task submitted!'}。而是等待 api 输出,直到任务完成。我正在关注来自fastapi 的文档。

fastapi: v0.70.0 蟒蛇:v3.8.10

我相信这个问题类似于here 所描述的问题。 请求帮助以使其成为非阻塞调用。

【问题讨论】:

标签: fastapi starlette


【解决方案1】:

我从 github 问题中学到了什么,

  • 您不能将async def 用于任务功能(它将在后台运行。)
  • 由于在后台进程中您无法访问协程,因此您的 async/await 将无法正常工作。
  • 您仍然可以尝试不使用 async/await。如果这也不起作用,那么您应该选择其他方法。

替代背景解决方案

  • Celery 是生产就绪的任务调度程序。因此,您可以使用your_task_function.delay(*args, **kwargs) 轻松配置和运行后台任务
  • 请注意, Celery 也不支持后台任务中的异步。因此,您需要编写的只是同步代码以在后台运行。

祝你好运:)

【讨论】:

  • 从fast api docs,我们实际上可以同时使用异步和普通方法。
  • 是的。但是从错误报告/问题中我提出了一种方法。它可能不正确。随便!!
【解决方案2】:

你的应用程序是如何运行的?

根据 uvicorn 文档,它默认运行 1 个 worker,这意味着只会同时发出一个进程。 尝试配置您的 uvicorn 以与更多工作人员一起运行。 https://www.uvicorn.org/deployment/

$ uvicorn example:app --port 5000 --workers THE_AMOUNT_OF_WORKERS
or
uvicorn.run("example:app", host="127.0.0.1", port=5000, workers=THE_AMOUNT_OF_WORKERS)

【讨论】:

  • 这似乎不是一个正确的方法,因为这样,如果我运行 4 个工作人员并有 20 个用户,那么一次只有 4 个能够运行他们的任务,因为这是一个阻止呼叫。
  • 如果您在 python 中使用异步等待,它应该正确处理它。检查你所做的事情是否支持异步工作。我建议您考虑使用 python celery,我的团队使用它为大量用户运行异步任务。取决于您的用户数量和完成任务所需的时间,我建议您扩展您的服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 2022-12-10
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多