Как остановить сельдерей, когда функция завершает свою задачу?
Я создал обратный отсчет и поместил этот отсчет в файл context_processor, задача в том, что когда кто-то создает заказ, у этого заказа есть время, и у каждой категории есть свое время, чтобы сделать этот заказ, поэтому, если я создал более одной категории, время будет отличаться в обратном отсчете.
Код работал у меня, но есть проблема, которая заключается в том, что иногда обратный отсчет работает и когда время доходит до "00:00:00", отсчет обрывается (это цель), а иногда, когда обратный отсчет работает и когда время доходит до "00:00:00", время повторяется снова (что приводит к неожиданному поведению)
Я пытаюсь остановить сельдерейный рабочий с помощью этого условия, но у меня ничего не получилось:
if _order_time == "00:00:00":
# _order.update(in_progress=False) TODO
self.expires = 0
На самом деле, я отследил, что происходит там, а затем получил проблему, так что когда обратный отсчет работает, я не должен делать никаких запросов, чтобы получить ожидаемое время, но если происходят какие-либо запросы, даже если это может быть "назад" или "вперед", начинает появляться неожиданное поведение для обратного отсчета.
Примечание: когда я запускаю celery worker, я выполняю следующую команду: $ python -m celery -A website worker -P solo
.
task.py
@app.task(bind=True)
def update_countdown(self, h, m, s, order):
while h > 0 or m > 0 or s > 0:
if h > 0 and m == 0:
h -= 1
m = 59
s = 59
elif m > 0 and s == 0:
m -= 1
s = 59
elif s > 0:
s -= 1
elif h == 0 and m == 0 and s == 0:
break
# Deserialize the DB queryset
queryset = json.loads(order)
user = User.objects.get(id=int(queryset[0]['fields']['user'])) # get user instance
_order = Order.objects.filter(user=user, in_progress=True).filter(id=int(queryset[0]['pk']))
_order_time = f"{h}:{m}:{s}"
_order.update(time_total=_order_time)
# Update order status
context = {"h": h, "m": m, "s": s}
update_order_status(user, _order, **context)
# Celery worker done
if _order_time == "00:00:00":
# print(self.backend.result_consumer.backend.__dict__)
# _order.update(in_progress=False) TODO
self.expires = 0
channel_layer = get_channel_layer() # Redis(host, port)
# Update order status channel
async_to_sync(channel_layer.group_send)(
"countdown_room",
{
"type": "update_status_consumer",
"payload": json.dumps(_order.get().status)
}
)
# Real-time order time in client-side channel
async_to_sync(channel_layer.group_send)(
"countdown_room",
{
"type": "countdown_consumer",
"payload": json.dumps({
'hour': _order.get().time_total.hour,
'min': _order.get().time_total.minute,
'sec': _order.get().time_total.second
})
}
)
time.sleep(1) # Trigger every 1 second
return CountDown(h, m, s).run_countdown()
context_processor.py
# Track the time of order
def countdown_state(hour: datetime.time.hour,
min: datetime.time.minute,
sec: datetime.time.second, order=None) -> datetime.time:
# Display the time in view
countdown = CountDown(hour=hour, min=min, sec=sec)
# Update the time in background
task = update_countdown.delay(hour, min, sec, order)
order_time = countdown.run_countdown()
return order_time # countdown view
# Run Countdown by (celery)
def realtime_countdown(request):
try:
orders = Order.objects.filter(in_progress=True)
# Tracking the order time by the online user
if request.user.is_authenticated:
order = orders.filter(user=request.user)
context = {'orders': order}
countdown_state_procedure = countdown_state(
context['orders'].get().time_total.hour,
context['orders'].get().time_total.minute,
context['orders'].get().time_total.second,
serialize("json", order),
)
context['order_time'] = countdown_state_procedure
return context
except:
return {}
Итак, мне нужно что-то, чтобы остановить запуск этого рабочего, есть ли способ сделать такую задачу?