请考虑以下任务:
import luigi
class YieldFailTaskInBatches(luigi.Task):
def run(self):
for i in range(5):
yield [
FailTask(i, j)
for j in range(2)
]
class YieldAllFailTasksAtOnce(luigi.Task):
def run(self):
yield [
FailTask(i, j)
for j in range(2)
for i in range(5)
]
class FailTask(luigi.Task):
i = luigi.IntParameter()
j = luigi.IntParameter()
def run(self):
print("i: %d, j: %d" % (self.i, self.j))
if self.j > 0:
raise Exception("i: %d, j: %d" % (self.i, self.j))
如果FailTask
,则j > 0
失败。 YieldFailTaskInBatches
在for循环中多次产生FailTask
,而YieldAllFailTasksAtOnce
产生数组中的所有任务。
如果我运行YieldFailTaskInBatches
,Luigi将运行在第一个循环中产生的任务,并且由于其中一个失败(i = 0, j = 1
),Luigi不会产生其余任务。如果我运行YieldAllFailTasksAtOnce
,Luigi将按预期运行所有任务。
我的问题是:即使某些任务失败,如何告诉路易吉继续在YieldFailTasksInBatches
上运行其余任务?可能吗?
我要问的原因是我要触发约40万个任务。我不想一次触发所有任务,因为这会使Luigi花太多时间来建立每个任务的需求(他们可以(具有1到400个要求)。我当前的解决方案是分批生产,一次很少生产,但是如果其中任何一个失败,任务就会停止,而其余的则不会生产。
this issue似乎可以解决此问题,但我想知道是否还有其他方法。
答案 0 :(得分:1)
这是非常骇人听闻的,但是它应该做您想要的:
class YieldAll(luigi.Task):
def run(self):
errors = list()
for i in range(5):
for j in range(2):
try:
FailTask(i, j).run()
except Exception as e:
errors.append(e)
if errors:
raise ValueError(f' all traceback: {errors}')
class FailTask(luigi.Task):
i = luigi.IntParameter()
j = luigi.IntParameter()
def run(self):
print("i: %d, j: %d" % (self.i, self.j))
if self.j > 0:
raise Exception("i: %d, j: %d" % (self.i, self.j))
因此,基本上,您正在luigi上下文之外运行任务。除非您输出目标,否则luigi永远不会知道任务是否运行。
luigi知道的唯一任务是YieldAll。如果任何YieldAll产生错误,则代码将捕获该错误并将YieldAll任务设置为失败状态。