我有一个django-viewflow工作流程,其中包括处理电子邮件,SMS等的三向Split()。由于这些活动中的每一项都可能需要较长的时间才能完成,因此我代表3个拆分的分支作为一对节点:
自定义节点如下所示:
class CeleryEvent(mixins.TaskDescriptionViewMixin,
mixins.NextNodeMixin, mixins.DetailViewMixin,
mixins.UndoViewMixin,
mixins.CancelViewMixin, Event):
....
activation_class = derived-from-AbstractJobActivation
setting task_type = "somestring"
在Celery作业完成时对Viewflow代码的调用遵循另一个question的模型,并且具体包括其中合并的锁。通常,结果可以正常工作。但是,偶尔我会从Viewflow 1.3.0的join.py中得到此异常:
tasks = flow_class.task_class._default_manager.filter(
flow_task=flow_task,
process=process,
status=STATUS.STARTED)
if len(tasks) > 1:
raise FlowRuntimeError('More than one join instance for process found')
这3个分支像这样加入:
close_join = flow.Join(wait_all=True). \
Next(this.alert_devops)
我对此感到有点困惑,因为在错误发生后进行检查,状态为{em> STARTED 的close_join
的流程和flow_task的组合确实发生了两次。我想知道我正在做的事情是否可能导致问题。据我所知,我的代码实际上都没有直接直接写入该表。
我确实注意到Task表没有没有unique_together('process', 'flow_task')
,我认为可能是因为Viewflow循环会导致相同的flow_task被打多次。由于我的代码还没有循环,所以我想知道暂时添加这样的约束是否是一个好主意。至少那么非法国家的创造者将成为失败的关键?
是否有可能在各个进程之间使用锁定是不安全的?由于Celery在机器中的多个进程上运行这段代码,这也许可以解释问题吗?
lock = self.flow_class.lock_impl(self.flow_class.instance)
with lock(self.flow_class, task.process_id):
#
# Re-acquire the task under a lock (see the StackOverflow thread).
#
task = self.flow_class.task_class._default_manager.get(pk=task.pk)
activation = self.activation_class()
activation.initialize(self, task)
activation.start()
activation.done()
答案 0 :(得分:0)
我相信缺少锁定确实是问题所在。根据{{3}}:
默认情况下不启用锁定。您需要选择适当的锁实现并启用它。