创建芹菜任务然后同步运行

时间:2021-07-11 19:14:14

My app gathers a bunch of phone numbers on a page. Once the user hits the submit button I create a celery task to call each number and give a reminder message then redirect them to a page where they can see the live updates about the call. I am using web sockets to live update the status of each call and need the tasks to execute synchronously as I only have access to dial out from one number.

我的应用程序在页面上收集了一堆电话号码。一旦用户点击提交按钮,我创建一个芹菜任务来呼叫每个号码并给出提醒消息,然后将它们重定向到一个页面,在那里他们可以看到有关呼叫的实时更新。我正在使用Web套接字来实时更新每个呼叫的状态,并且需要同步执行任务,因为我只能从一个号码拨出。

So once the first call/task is completed, I want the next one to fire off.

因此,一旦第一个呼叫/任务完成,我希望下一个呼叫/任务启动。

I took a look at CELERY_ALWAYS_EAGER settings but it just went through the first iteration and stopped.

我看了一下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') 

2 个解决方案

#1


4  

if you want to fire each call one after another, why dont you wrap all the calls in one task

如果你想一个接一个地发起每个呼叫,为什么不把所有的呼叫都包裹在一个任务中

@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


18  

If you look at the celery DOCS on tasks you see that to call a task synchronosuly, you use the apply() method as opposed to the apply_async() method.

如果您在任务上查看celery DOCS,您会看到同步调用任务,则使用apply()方法而不是apply_async()方法。

So in your case you could use:

所以在你的情况下你可以使用:

 reminder.apply(args=[number])

The DOCS also note that:
If the CELERY_ALWAYS_EAGER setting is set, it will be replaced by a local apply() call instead.

DOCS还注意到:如果设置了CELERY_ALWAYS_EAGER设置,它将被替换为本地apply()调用。

Thanks to @JivanAmara who in the comments reiterated that when using apply(), the task will run locally(in the server/computer in which its called). And this can have ramifications, if you intended to run your tasks across multiple servers/machines.

感谢@JivanAmara,他在评论中重申,当使用apply()时,任务将在本地运行(在其调用的服务器/计算机中)。如果您打算跨多个服务器/计算机运行任务,这可能会产生分歧。

#1


4  

if you want to fire each call one after another, why dont you wrap all the calls in one task

如果你想一个接一个地发起每个呼叫,为什么不把所有的呼叫都包裹在一个任务中

@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


18  

If you look at the celery DOCS on tasks you see that to call a task synchronosuly, you use the apply() method as opposed to the apply_async() method.

如果您在任务上查看celery DOCS,您会看到同步调用任务,则使用apply()方法而不是apply_async()方法。

So in your case you could use:

所以在你的情况下你可以使用:

 reminder.apply(args=[number])

The DOCS also note that:
If the CELERY_ALWAYS_EAGER setting is set, it will be replaced by a local apply() call instead.

DOCS还注意到:如果设置了CELERY_ALWAYS_EAGER设置,它将被替换为本地apply()调用。

Thanks to @JivanAmara who in the comments reiterated that when using apply(), the task will run locally(in the server/computer in which its called). And this can have ramifications, if you intended to run your tasks across multiple servers/machines.

感谢@JivanAmara,他在评论中重申,当使用apply()时,任务将在本地运行(在其调用的服务器/计算机中)。如果您打算跨多个服务器/计算机运行任务,这可能会产生分歧。