【问题标题】:How to start celery task after django request finisheddjango请求完成后如何启动芹菜任务
【发布时间】:2014-04-14 05:21:00
【问题描述】:

只有在 django 请求完成后,我才需要运行 celery 任务。 有可能吗?

【问题讨论】:

  • 针对所有请求或特定视图?
  • 对于所有请求,因为我编写事务重要服务。所以我需要在请求完成后开始所有任务。
  • 尝试在中间件中启动任务?
  • 你可以看看使用request_finished 信号。 docs.djangoproject.com/en/dev/ref/signals/…

标签: django celery django-celery


【解决方案1】:

我发现确保在请求完成后执行任务的最佳方法是编写自定义中间件。在process_response 方法中,您可以处理不会过多影响页面加载时间或性能的任何快速操作。其他任何事情,你都可以交给 Celery。在调用 process_response (AFAICT) 之前,所有保存或数据库事务都已完成。

【讨论】:

    【解决方案2】:

    您可以在后台运行任务,使用 celery 的延迟方法。我的意思是在返回响应之前,您可以调用延迟方法将任务置于后台。

    类似这样的事情:

    task_name.delay(arg1, arg2, ...)
    

    通过这样做,您的任务将被置于后台并异步运行,这不会阻塞请求响应周期。

    【讨论】:

    • 然而,可能发生的是任务在事务提交之前被执行。如果您已将某些内容添加到预期任务将在其上运行的数据库表中,则即使使用 .delay(...) 也可能会失败。我相信最初的问题是如何避免这种情况。
    【解决方案3】:

    试试这样的:

    Django 在每个请求结束时发送 request_finished。
    您可以通过 sender 参数访问请求对象,

    from django.dispatch import receiver
    from django.core.signals import request_finished
    
    from app.tasks import my_task
    
    @receiver(request_finished)
    def add_celery_task(sender):
        if sender.__name__ != 'StaticFilesHandler':
            my_task.delay()
    

    如果您在开发环境中运行服务器,最好检查发件人的名称,以避免为您服务的每个静态文件添加过多的 celery 任务。

    【讨论】:

    • 如果你在 requset_finished 接收器回调中添加断点仍然停止响应
    猜你喜欢
    • 2017-12-08
    • 2013-01-12
    • 2020-05-19
    • 2020-07-09
    • 2021-10-01
    • 2011-04-21
    • 2013-07-17
    • 1970-01-01
    • 2021-10-15
    相关资源
    最近更新 更多