我正在使用celerybeat开始执行许多次要任务的主要任务。我已经写了两个任务。
有没有办法轻松做到这一点? Celery是否允许从任务中运行任务?
我的例子:
@task
def compute(users=None):
if users is None:
users = User.objects.all()
tasks = []
for user in users:
tasks.append(compute_for_user.subtask((user.id,)))
job = TaskSet(tasks)
job.apply_async() # raises a IOError: Socket closed
@task
def compute_for_user(user_id):
#do some stuff
从celerybeat调用 compute
,但在尝试运行apply_async
时会导致IOError。有什么想法吗?
答案 0 :(得分:28)
回答您的开场提问:从2.0版本开始,Celery提供了一种从其他任务启动任务的简便方法。你称之为“次要任务”的是它所谓的“子任务”。请参阅Sets of tasks, Subtasks and Callbacks的文档,@ Paperino非常友好地链接到该文档。
对于3.0版,Celery更改为使用groups来处理此行为以及其他类型的行为。
您的代码显示您已熟悉此界面。你的实际问题似乎是,“当我尝试运行我的一组子任务时,为什么我得到'套接字已关闭'IOError
?”我认为没有人可以回答这个问题,因为您没有提供有关您的计划的足够信息。你的摘录不能按原样运行,所以我们无法检查你为自己所拥有的问题。请发布随IOError
提供的堆栈跟踪,运气好的话,有人可以帮助您使用crasher。
答案 1 :(得分:9)
因为版本3.0'TaskSet'不再是这个术语了......组,链和弦作为一种特殊类型的子任务是新的东西,见http://docs.celeryproject.org/en/3.1/whatsnew-3.0.html#group-chord-chain-are-now-subtasks
答案 2 :(得分:9)
你可以使用这样的东西(3.0中的支持)
g = group(compute_for_user.s(user.id) for user in users)
g.apply_async()
答案 3 :(得分:0)
对于提到的IOError,尽管这里的信息不足以说明是什么原因造成的,但我的猜测是您试图在task函数内部建立连接,因此无论何时调用任务,都会建立一个新的连接。如果要将该任务调用数千次,则将有数千个连接。这将淹没系统套接字管理器,而IOError是它的抱怨。