Activiti process event summary

The difference between boundary events and intermediate events: boundary events are related to associated nodes. For example, a timed boundary event is set on a node. After this event, if the node has not yet been approved, you can choose to cancel the activity, which means you do not need to go to the next One node. An intermediate event is an event defined after a node. For example, an intermediate defined event is defined after a node. After the node is approved, it will flow to the next node after the timing time is exceeded. In summary, boundary events are for nodes, and intermediate events are for processes.

1. News event

The message event will reference a named message. Each message has a name and content. Unlike signals, message events are always sent directly to one recipient.
If the message should trigger the start of a new process instance, choose one of the following RuntimeService methods to execute:

//根据消息名称发起流程
ProcessInstance startProcessInstanceByMessage(String messageName);
//传入消息名称和流程变量发起流程
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
//传入消息名称,流程变量和业务key发起流程
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object> processVariables);

These methods allow the corresponding message flow instance to be started.
If the message needs to be processed by the running process instance, first find the corresponding process instance based on the message and then trigger the waiting process. RuntimeService provides the following methods to trigger the process to continue execution based on the subscription of message events:

//根据消息名称和流程执行ID触发消息
void messageEventReceived(String messageName, String executionId);
void messageEventReceived(String messageName, String executionId, HashMap<String, Object> processVariables);

#Query message event subscription

Activiti supports message start events and intermediate message events.
In the case of a message start event, the message event subscription is assigned to a specific processdefinition. This news subscription can be queried using ProcessDefinitionQuery:

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
messageEventSubscription("newCallCenterBooking").singleResult();

• Because there can only be one process definition associated with the subscription point of the message at a time, the query always returns 0 or a result. If the process definition is updated, only the latest version of the process definition will be subscribed to the message event.
• When a message event is captured in the middle, the message event subscription will be assigned to a specific execution. This news event subscription can be queried using ExecutionQuery:

Execution execution = runtimeService.createExecutionQuery()
    .messageEventSubscriptionName("paymentReceived")
    .variableValueEquals("orderId", message.getOrderId()) .singleResult();

• This query can call the corresponding query, usually process-related information (here, at most one process instance can correspond to orderId).
Insert picture description here
The message definition is for the process, and the message defined here can be selected on the node. As shown in the figure, after the application is submitted, the process waits in the intermediate message, and will continue to flow until the message is received.
Insert picture description here

2. Signal event

The signal event references a named signal. Signal global events (broadcast semantics). Will be sent to all activated processors.
The trigger signal event can be triggered by a process instance via the bpmn node or via API. The following methods in org.activiti.engine.RuntimeService can be used to manually trigger a signal.

RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);                           

The difference between signalEventReceived(String signalName); and signalEventReceived(String signalName, String executionId); is that the first method sends the signal to all subscribed processors globally (broadcast semantics), and the second method only sends information to Specify the process instance.
Capture signal events, which can be captured by intermediate capture signal events or boundary information events.

To query the subscription of signal events, you can query the execution of all subscribed specific signal events:

List<Execution> executions = runtimeService.createExecutionQuery()
    .signalEventSubscriptionName("alert").list();

We can use the signalEventReceived(String signalName, String executionId) method to send signals to these executions.

Signal event range. By default, the signal will be broadcast within the scope of the process engine. In other words, you can throw a signal event in a process instance, and other process instances defined by different processes can listen to this event. Sometimes you only want to respond to this signal event in the same process instance, you can use the scope attribute defined by the signal event to set it to the process instance.

When defining a signal, you can choose the scope of the event, either at the global or process instance level.
Insert picture description here
For the signal of the process instance , the signal must be thrown in the process, that is, the intermediate signal throw event is defined.
Insert picture description here

As shown in the figure, a signal will be thrown after the supervisor's approval, and the execution will continue after the signal is captured.
Insert picture description here

Activiti source code analysis

for (SignalEventSubscriptionEntity signalEventSubscriptionEntity : signalEvents) {
    
    
      // We only throw the event to globally scoped signals.
      // Process instance scoped signals must be thrown within the process itself
      //这里只实现了全局信号的抛出,流程实例级别的需要流程自己抛出
      if (signalEventSubscriptionEntity.isGlobalScoped()) {
    
    
        
        if (executionId == null && Activiti5Util.isActiviti5ProcessDefinitionId(commandContext, signalEventSubscriptionEntity.getProcessDefinitionId())) {
    
    
          Activiti5CompatibilityHandler activiti5CompatibilityHandler = Activiti5Util.getActiviti5CompatibilityHandler(); 
          activiti5CompatibilityHandler.signalEventReceived(signalEventSubscriptionEntity, payload, async);
          
        } else {
    
    
          Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
              ActivitiEventBuilder.createSignalEvent(ActivitiEventType.ACTIVITY_SIGNALED, signalEventSubscriptionEntity.getActivityId(), eventName, 
                  payload, signalEventSubscriptionEntity.getExecutionId(), signalEventSubscriptionEntity.getProcessInstanceId(), 
                  signalEventSubscriptionEntity.getProcessDefinitionId()));
          
          eventSubscriptionEntityManager.eventReceived(signalEventSubscriptionEntity, payload, async);
        }
      }
    }

The signal implementation at the process instance level is mainly

org.activiti.engine.impl.bpmn.helper.SignalThrowingEventListener # onEvent

public void onEvent(ActivitiEvent event) {
    
    
    if (isValidEvent(event)) {
    
    

      if (event.getProcessInstanceId() == null && processInstanceScope) {
    
    
        throw new ActivitiIllegalArgumentException("Cannot throw process-instance scoped signal, since the dispatched event is not part of an ongoing process instance");
      }

      CommandContext commandContext = Context.getCommandContext();
      EventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.getEventSubscriptionEntityManager();
      List<SignalEventSubscriptionEntity> subscriptionEntities = null;
      if (processInstanceScope) {
    
    
        subscriptionEntities = eventSubscriptionEntityManager.findSignalEventSubscriptionsByProcessInstanceAndEventName(event.getProcessInstanceId(), signalName);
      } else {
    
    
        String tenantId = null;
        if (event.getProcessDefinitionId() != null) {
    
    
          ProcessDefinition processDefinition = commandContext.getProcessEngineConfiguration().getDeploymentManager().findDeployedProcessDefinitionById(event.getProcessDefinitionId());
          tenantId = processDefinition.getTenantId();
        }
        subscriptionEntities = eventSubscriptionEntityManager.findSignalEventSubscriptionsByEventName(signalName, tenantId);
      }

      for (SignalEventSubscriptionEntity signalEventSubscriptionEntity : subscriptionEntities) {
    
    
        eventSubscriptionEntityManager.eventReceived(signalEventSubscriptionEntity, null, false);
      }
    }
  }

You can take a look

3. Event Gateway

The event gateway allows to determine the flow direction based on the event. Each outgoing sequence flow of the gateway must be connected to an intermediate capture event. When the process reaches an event-based gateway, the gateway will enter a waiting state: execution will be suspended. At the same time, a relative event subscription is created for each outgoing sequence flow.
Note that the outgoing sequence flow based on the event gateway is different from the normal sequence flow. These sequence flows will not really "execute". Instead, they let the process engine decide which events need to be subscribed to to the process based on the event gateway. The following conditions should be considered:
• The event-based gateway must have two or more outgoing sequence flows.
• Based on the event gateway, only the intermediateCatchEvent type can be used. (Activiti does not support the connection of ReceiveTask after the event-based gateway.)
• IntermediateCatchEvent connected to the event-based gateway can only have one incoming sequence flow.

As shown in the figure, this event gateway has two exits, one is subscribed to an intermediate timing capture event, and the other is subscribed to an intermediate message capture event. The process will end when no message is received after the set timing time.
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_34758074/article/details/104644557