我有三个任务:
@app.task(name='timey')
def timey():
print "timey"
while True:
pass
return 1
@app.task(name='endtimey')
def endtimey():
for i in range(10):
print "ENDTIMEY", time()
sleep(3)
return 1
@app.task(name='nexttask')
def nexttask(n):
print "NEXT TASK"
return 1
如果我做的唯一事情是连锁结束和下一步 -
chain(endtimey.s() | nexttask.s()).delay()
一切都按预期工作。我看到ENDTIMEY <current time>
打印十次,然后在芹菜日志中打印NEXT TASK
。但是,如果我使用无限任务timey
填充7名工作人员,然后将endtimey
和nexttask
链接在一起 -
for i in range(7):
timey.s().delay()
chain(endtimey.s() | nexttask.s()).delay()
所有timey
任务将由8名工作人员中的7人接收,endtimey
将在第8名工作人员上运行,之后日志将显示nexttask
已有已收到,但nexttask
将无法运行。
为什么会这样?
此外,如果我杀死芹菜服务器然后重新启动它,nexttask
将是第一个运行。
这是一个人为的例子,但是在一个更复杂的情况下我遇到了一个问题,即芹菜工人在完成当前任务后没有完成排队任务。如果我在那个例子中重新启动芹菜,那么自由工作者将再次开始接收任务。
答案 0 :(得分:4)
听起来这个问题是芹菜的默认预取行为。每个工作人员将在当前处于最大容量时提前保留一定数量的任务,这称为Prefetch Multiplier。
这样做的原因是当你有大量的短任务时,如果任务已被预取并准备好立即执行,你的整体吞吐量会高得多。
问题在于,当你有很多长时间运行的任务或者长短任务的混合时,即使其他工作人员可以处理它,任务也可以被繁忙的工作人员保留和阻止。
因此,在您的情况下,您可能需要将预取乘数降低到1.