【问题标题】:How to schedule a celery task without blocking django如何在不阻塞 django 的情况下安排 celery 任务
【发布时间】:2019-10-23 02:46:21
【问题描述】:

我有一个 Django 服务,它注册大量客户端并呈现包含计时器(比如说 800 秒)的有效负载,之后客户端应该被服务暂停(在 MongoDB 中将状态注册为暂停)

我正在使用 rabbitmq 作为代理运行 celery,如下所示:

芹菜/tasks.py `

@app.task(bind=True, name='suspend_nf')
def suspend_nf(pk):
    collection.update_one({'instanceId': str(pk)},
                          {'$set': {'nfStatus': 'SUSPENDED'}})

`

并在 django 视图中调用任务,例如:

api/views.py `

def put(self, request, pk):
    now = datetime.datetime.now(tz=pytz.timezone(TIME_ZONE))
    timer = now + datetime.timedelta(seconds=response_data["heartBeatTimer"])
    suspend_nf.apply_async(eta=timer)
    response = Response(data=response_data, status=status.HTTP_202_ACCEPTED)
    response['Location'] = str(request.build_absolute_uri())

`

我在这里错过了什么?

【问题讨论】:

    标签: django mongodb django-rest-framework celery scheduled-tasks


    【解决方案1】:

    您是要求您的视图完全阻塞还是视图正在等待“ETA”完成执行?
    您收到任何错误吗?

    尝试使用countdown 参数而不是eta
    在您的情况下,它会更好,因为您不需要操纵日期。
    像这样:suspend_nf.apply_async(countdown=response_data["heartBeatTimer"])
    让我们看看你的视图是否会有一些不同的行为。

    【讨论】:

    • 不,我不是要阻止视图,我希望视图在后台启动任务以稍后修改 MongoDB 并立即返回响应而不阻塞
    【解决方案2】:

    我终于找到了解决方法,因为在一个小项目上工作,我真的不需要 Celery + rabbitmq 一个简单的线程来完成这项工作。

    任务如下所示:

    def suspend_nf(pk, timer):
        time.sleep(timer)
        collection.update_one({'instanceId': str(pk)},
                              {'$set': {'nfStatus': 'SUSPENDED'}})
    

    并在视图内部调用:

    timer = int(response_data["heartBeatTimer"])
    thread = threading.Thread(target=suspend_nf, args=(pk, timer), kwargs={})
    thread.setDaemon(True)
    thread.start()
    

    【讨论】:

      猜你喜欢
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      相关资源
      最近更新 更多