是什么导致视图流抛出“找到了一个以上的用于处理的联接实例”

时间:2018-09-19 10:14:02

标签: django-viewflow

我有一个django-viewflow工作流程,其中包括处理电子邮件,SMS等的三向Split()。由于这些活动中的每一项都可能需要较长的时间才能完成,因此我代表3个拆分的分支作为一对节点:

  • 一个普通的Handler()节点,它产生一个Celery作业。
  • 自定义芹菜等待节点。

自定义节点如下所示:

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()

1 个答案:

答案 0 :(得分:0)

我相信缺少锁定确实是问题所在。根据{{​​3}}:

  

默认情况下不启用锁定。您需要选择适当的锁实现并启用它。