Как завершить все параллельные действия ViewFlow (Terminate End)? - PullRequest
0 голосов
/ 13 сентября 2018

Я хочу выпустить этот поток: enter image description here

Я пытался использовать только один узел End, но другая ветвь остается активной. Как завершить все активные задачи и весь процесс, когда заканчивается одна ветка?

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

То, что вам нужно, называется шлюзом на основе событий в BPMN, и он не поддерживается Viewflow из коробки, вам нужно реализовать код, предоставленный kmmbvnr .

enter image description here

Что делает этот шлюз, так это активирует исходящие пути и ожидает завершения любой из задач, а когда первая задача выполнена,другие пути или задачи отменяются.

Когда вы используете потоки, которые возвращаются в один из путей, вы должны учитывать, что никакие другие пути не активны, только тот, который сначала выполнил задачу.

0 голосов
/ 18 сентября 2018

По потоку спецификации BPNM. Конец завершает только входящие в него токены задач.Параллельная задача остается незавершенной.

Если у вас есть ситуация, когда один из параллельных потоков необходимо отменить, в BPMN такие процессы, смоделированные сложным разделенным шлюзом, ожидают, пока последующая задача завершит свою работу, и отменят другие.Вот реализация эскиза для узла с разделенным первым видом потока.Вы можете адаптировать его для вашего конкретного случая.

class SplitFirst(flow.Split):
    shape = {
        'width': 50,
        'height': 50,
        'svg': """
            <path class="gateway" d="M25,0L50,25L25,50L0,25L25,0"/>
        <text class="gateway-marker" font-size="32px" x="25" y="35">1</text>
        """
    }

    def on_signal(self, sender, **signal_kwargs):
        task = signal_kwargs['task']
        split_first = task.previous.filter(flow_task=self).first()
        if split_first:
            for leading in split_first.leading.all().exclude(pk=task.pk):
                activation = leading.activate()
                if hasattr(activation, 'cancel') and activation.cancel.can_proceed():
                    activation.cancel()

    def ready(self):
        super(SplitFirst, self).ready()

        task_finished.connect(
            self.on_signal,
            sender=self.flow_class,
            dispatch_uid="sample.splitfirst/{}.{}.{}".format(
                self.flow_class.__module__, self.flow_class.__name__, self.name
            )
        )
...