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()时,任务将在本地运行(在其调用的服务器/计算机中)。如果您打算跨多个服务器/计算机运行任务,这可能会产生分歧。