如何在不阻止Django的情况下安排芹菜任务

时间:2019-06-07 15:08:11

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

我有一个Django服务,该服务注册了许多客户端,并在该客户端应被该服务挂起(将状态更改为MongoDB中注册为SUSPENDED)后,渲染包含计时器的有效负载(比如说800s)

我正在以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())

`

我在这里想念什么?

2 个答案:

答案 0 :(得分:0)

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

尝试使用countdown参数代替eta
就您而言,这是更好的选择,因为您不需要操纵日期。
像这样:suspend_nf.apply_async(countdown=response_data["heartBeatTimer"])
让我们看看您的视图是否会有不同的行为。

答案 1 :(得分:0)

我终于找到了解决方法,因为在一个小项目上工作,所以我真的不需要Celery + rabbitmq了,一个简单的Threading就可以了。

任务看起来像这样:

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()