Как остановить сельдерей, когда функция завершает свою задачу?

Я создал обратный отсчет и поместил этот отсчет в файл 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 {}

Итак, мне нужно что-то, чтобы остановить запуск этого рабочего, есть ли способ сделать такую задачу?

Вернуться на верх