Various gateways in Flowable, how many do you know?

2022.04.13
Various gateways in Flowable, how many do you know?

When the process reaches an event-based gateway, the gateway enters a wait state: execution is suspended.  At the same time, a relative event subscription is created for each outgoing sequence flow.

gateway

Gateways are used to control the flow of processes.

1. Exclusive gateway

Exclusive gateways (also called XOR gateways, or more specialized, exclusive data-based gateways) are used to model decisions in processes.  When execution reaches this gateway, all egress sequence flows are evaluated in the order defined by them.  Select the first sequence flow whose condition evaluates to true (when no condition is set, the sequence flow is considered to be true) to continue the process.

Note that the meaning of exit sequence flow here is not the same as the general case in BPMN 2.0.  In general, the sequence flow for which all conditions evaluate to true will be selected and executed in parallel.  With an exclusive gateway, only one sequence flow is selected.  When the conditions of multiple sequence flows are all evaluated to true, only the sequence flow first defined in the XML will be selected to continue the process.  If there is no optional sequence flow, an exception will be thrown.

An exclusive gateway is represented by a standard gateway (diamond) with an 'X' icon inside, which means XOR. Note that gateways without icons inside default to exclusive gateways. The BPMN 2.0 specification does not allow mixing diamonds with and without an X in the same process.

Case:

  /**
     * 部署流程
     */
    @Test
    public void deploy(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("请假流程-排他网关.bpmn20.xml")
                .name("请求流程-排他网关")
                .deploy();
        System.out.println("deploy.getId() = " + deploy.getId());
        System.out.println(deploy.getName());
    }

    /**
     * 启动流程实例
     */
    @Test
    public void runProcess(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 给流程定义中的UEL表达式赋值
        Map<String,Object> variables = new HashMap<>();
        // variables.put("g1","group1");
        variables.put("num",3); // 给流程定义中的UEL表达式赋值
        runtimeService.startProcessInstanceById("holiday-exclusive:1:4",variables);
    }


    /**
     * 启动流程实例
     */
    @Test
    public void setVariables(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 给流程定义中的UEL表达式赋值
        Map<String,Object> variables = new HashMap<>();
        // variables.put("g1","group1");
        variables.put("num",4); // 给流程定义中的UEL表达式赋值
        runtimeService.setVariables("12503",variables);
    }



    /**
     * 完成任务
     */
    @Test
    public void completeTask(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery()
                //.processInstanceId("2501")
                .processDefinitionId("holiday-exclusive:1:4")
                .taskAssignee("zhangsan")
                .singleResult();
        if(task != null){
            // 完成任务
            taskService.complete(task.getId());
            System.out.println("完成Task");
        }
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • twenty one.
  • twenty two.
  • twenty three.
  • twenty four.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.

If all the conditions of the line going out from the gateway are not satisfied, a system exception will be thrown .

But note that the task is not introduced, or the original task, we can reset the process variables.

@Test
    public void setVariables(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 给流程定义中的UEL表达式赋值
        Map<String,Object> variables = new HashMap<>();
        // variables.put("g1","group1");
        variables.put("num",4); // 给流程定义中的UEL表达式赋值
        runtimeService.setVariables("12503",variables);
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

We can define conditions directly on the connection line, so why should there be an exclusive gateway? In the case of direct connection, if the conditions are not met, the process ends, which is an abnormal end!

2. Parallel Gateway

Parallel gateways allow the process to be divided into multiple branches, and multiple branches can also be aggregated together. The functions of parallel gateways are based on incoming and outgoing sequence flows:

  • fork branch: All outgoing sequence flows after parallelization, create a concurrent fork for each sequence flow.
  • Join aggregation: All incoming branches that arrive at the parallel gateway and wait here, until all the branches that enter the sequence flow arrive, the process will pass through the aggregation gateway.

Note that if the same parallel gateway has multiple incoming and multiple outgoing sequence flows, it has both branching and aggregation capabilities. At this time, the gateway will first aggregate all incoming sequence flows, and then split into multiple parallel branches.

The main difference from other gateways is that parallel gateways do not resolve conditions. Even if conditions are defined in the sequence flow, they are ignored.

Case:

When we execute the creation of a leave request, when we reach the location of the parallel gateway, there are two records in the ACT_RU_TASK table.

Then there are three records in ACT_RU_EXECUTION at the same time, and there are two execution instances corresponding to one task.

3. Include gateway

Inclusive gateways can be seen as a combination of exclusive gateways and parallel gateways. As with exclusive gateways, you can define conditions on outgoing sequence flows, and include gateways will resolve them. But the main difference is that containment gateways can choose more than one sequential stream, just like parallel gateways.

The functions that contain gateways are based on incoming and outgoing sequence flow:

  • Branching: The conditions of all outgoing sequence flows are resolved, and the sequence flows that result in true continue to execute in parallel, creating a branch for each sequence flow.
  • Convergence: All parallel branches arrive at the containing gateway and enter a waiting state until each branch of the incoming sequence flow containing the process token arrives. This is the biggest difference from parallel gateways. In other words, the containment gateway will only wait for incoming sequence flows that are selected for execution. After convergence, the process continues through the containment gateway.

4. Event Gateway

The event gateway allows to determine the flow direction based on the event. Each outgoing sequence flow of the gateway is connected to an intermediate capture event. When the process reaches an event-based gateway, the gateway enters a wait state: execution is suspended. At the same time, a relative event subscription is created for each outgoing sequence flow.

The outgoing sequence flow of the event gateway is different from the normal sequence flow. These sequence flows do not really "execute", instead they let the process engine decide which events the process executing to the event gateway needs to subscribe to. The following conditions are to be considered:

The event gateway must have two or more outgoing sequence flows;

After the event gateway, only the intermediateCatchEvent type can be used (activiti does not support connecting ReceiveTask based on the event gateway);

An intermediate capture event connected to an event gateway must have only one ingress sequence flow.