Создавайте задачи сельдерея, затем выполняйте синхронно

Мое приложение собирает кучу телефонных номеров на странице. Когда пользователь нажимает кнопку отправки, я создаю задачу celery для вызова каждого номера и отправки напоминания, а затем перенаправляет их на страницу, где они могут видеть текущие обновления о вызове. Я использую веб-сокеты, чтобы жить, обновляя статус каждого вызова и нуждаясь в том, чтобы задачи выполнялись синхронно, поскольку у меня только есть доступ для набора номера из одного номера.

Итак, как только первый вызов/задача будет завершен, я хочу, чтобы следующий из них погас.

Я посмотрел настройки CELERY_ALWAYS_EAGER, но он просто прошел первую итерацию и остановился.

@task
def reminder(number):
    # CODE THAT CALLS NUMBER HERE....

def make_calls(request):
    for number in phone_numbers:                     
        reminder.delay(number)      

    return redirect('live_call_updates') 

Ответы

Ответ 1

если вы хотите запускать каждый вызов один за другим, почему вы не переносите все вызовы в одну задачу?

@task
def make_a_lot_of_calls(numbers):
    for num in numbers:
        # Assuming that reminder blocks till the call finishes
        reminder(number)

def make_calls(request):
    make_a_lot_of_calls.delay(phone_numers)                          
    return redirect('live_call_updates') 

Ответ 2

Если вы посмотрите на DOCS сельдерея на задачи, вы увидите, что для синхронного вызова задачи вы используете метод apply(), а не метод apply_async().

Итак, в вашем случае вы можете использовать:

 reminder.apply(args=[number])

DOCS также отмечает, что:
If the CELERY_ALWAYS_EAGER setting is set, it will be replaced by a local apply() call instead.

Спасибо @JivanAmara, который в комментариях повторил, что при использовании apply() задача будет выполняться локально (на сервере/компьютере, на котором ее вызывается). И это может иметь последствия, если вы планируете выполнять свои задачи на нескольких серверах/машинах.