This is the second day of my participation in Gwen Challenge

Custom extension

  • The BPMN 2.0 standard is a good thing for all parties
    • Users don’t have to worry about being tied to a vendor’s proprietary solution
    • Frameworks, especially open source frameworks like Activiti, can provide the same functionality, or even better implementation, as the big vendors do
    • According to the BPMN 2.0 standard, moving from a large vendor solution to Activiti is a simple and smooth process
  • The downside of the BPMN 2.0 standard is that
    • It is often the result of a lot of discussion and compromise between different companies
    • As a developer reading the BPMN 2.0 XML of the process definition, it sometimes feels like too much work to do with this structure and approach
    • So Activiti makes simplifying development a top priority, using features called Activiti BPMN extensions, which are new constructs or methods to simplify corresponding constructs that are not part of the BPMN 2.0 specification
  • Notes for developing custom extensions according to the BPMN 2.0 standard
    • The premise of custom extensions is that there is always an easy way to convert to standard methods. Therefore, when using a custom extension, you can cancel it in time
    • When using custom extensions, it is always clear that new XML elements, attributes… For example, the Activiti: namespace prefix is used
    • The goal of the extension is to eventually add to the next version of the BPMN specification, or at least to lead to discussion of specific BPMN structures

The event

  • Events are used to indicate what happened during the life cycle of a process. Events are always drawn in a circle
  • In BPMN 2.0, there are two main categories of events:Catching eventsThrowing events:
    • Catching: When a process executes an event, it waits to be triggered. The types triggered are determined by the type declarations in the internal diagram or XML. Captured and triggered events are distinguished in display terms by whether or not the internal chart is populated (white)
    • Throwing: An event is triggered when a process executes an event. The types triggered are determined by the type declarations in the internal diagram or XML. Trigger and capture events are distinguished in terms of display by whether or not the internal chart is populated (black)

An event definition

  • The event definition determines the semantics of the event. If there is no event definition, the event does nothing special. A start event without a set event definition does nothing when the process is started
  • If we add an event definition to the start event (such as a timer event definition) we declare the event type for the start process (at which point the timer event listener will be fired)

Timer Event Definition

  • Timer events are events that are triggered at a specified time
  • Timer events can be used for start, intermediate, and boundary events
  • == Timer definition element :==
  • TimeDate: time when the event is triggered. A definite time specified in ISO8601 format:
<timerEventDefinition>
    <timeDate>2011-03-11T12:13:14</timeDate>
</timerEventDefinition>
Copy the code
  • Uration: specifies how long to wait before timer. TimeDuration can be set to a child of timerEventDefinition using the format specified in ISO8601
<timerEventDefinition>
	<! -- Wait 10 days -->
    <timeDuration>P10D</timeDuration>
</timerEventDefinition>
Copy the code
  • timeCycle: Specifies the interval for repeated execution.You can use it to periodically start a process instance or to send multiple reminders for a timeout. The timeCycle element can be used in two formats:
    • Format of the ISO8601 standard
    • Cron expression
<timerEventDefinition>
	<! -- Repeat 3 times, 10 hours apart -->
    <timeCycle>R3/PT10H</timeCycle>
</timerEventDefinition>
Copy the code
  • Every 5 minutes from the hour:
0 0/5 * * *, right?Copy the code
  • = = note: = =
    • The first number represents seconds, not minutes as is common in Unix CRon
    • Repeating time cycles is a better way to deal with relative time by calculating specific points in time: the start time of a user task
    • Cron expressions can handle absolute time, which is especially useful for timed start events
  • Using expressions in timer event definitions can influence that timer definition through process variables: The process definition must contain a string in ISO8601(or CRON) format to match the corresponding time type
  <boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
     <timerEventDefinition>
        <timeDuration>${duration}</timeDuration>
     </timerEventDefinition>
  </boundaryEvent>
Copy the code

JobExecutorActivate in activiti.cfg. XML must be set to true to disable the job actuator by default

Error event definition

  • Error events are triggered by specified errors
  • = =Note:= =
    • BPMN errors are completely different from Java exceptions:
      • BPMN error events are designed to model business exceptions
      • Java exceptions are handled in a specific way
  • The error event definition refers to an error element, which is caught by an error event handler that references the same error element
<endEvent id="myErrorEndEvent">
	<! -- reference an error statement -->
  <errorEventDefinition errorRef="myError" />
</endEvent>
Copy the code

Signal event definition

  • The signal event refers to a named signal
  • Signal global-scope events (broadcast semantics). Are sent to all active processors
  • SignalEventDefinition uses the signalEventDefinition element. The signalRef attribute refers to the Signal child defined in the Definitions root node (signalEventDefinition refers to the same signal element).
<! -- Process instance in which a signal is thrown and caught by an intermediate event -->
<definitions... >
        <! -- declaration of the signal -->
        <signal id="alertSignal" name="alert" />

        <process id="catchSignal">
                <intermediateThrowEvent id="throwSignalEvent" name="Alert">
                        <! -- signal event definition -->
                        <signalEventDefinition signalRef="alertSignal" />
                </intermediateThrowEvent>.<intermediateCatchEvent id="catchSignalEvent" name="On Alert">
                        <! -- signal event definition -->
                        <signalEventDefinition signalRef="alertSignal" />
                </intermediateCatchEvent>.</process>
</definitions>
Copy the code
Trigger event
  • A signal can be triggered by a process instance through a BPMN node. It can also be triggered by an API
  • In the org. Activiti. Engine. RuntimeService method can be used to manually trigger a signal:
RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);
Copy the code
  • SignalEventReceived (String signalName): Processing that sends signals to all subscriptions globally (broadcast semantics)
  • SignalEventReceived (String signalName, String executionId): Sends the signal to the specified execution
Capture signal event
  • Signal events can be captured by intermediate signal events or boundary information events
Query subscriptions to signal events
  • Queries the execution of all subscribed specific signal events
 List<Execution> executions = runtimeService.createExecutionQuery()
      .signalEventSubscriptionName("alert")
      .list();
Copy the code
  • Use signalEventReceived(String signalName, String executionId) to send signals to these implementations
Signal event range
  • By default, signals are broadcast at the scope of the process engine: a signal event is thrown in one process instance and can be heard by other process instances with different process definitions
  • Sometimes you only need to respond to this signal event within the same process instance: synchronization mechanism within the process instance if two or more activities are mutually exclusive
  • To limit the scope of a signal event, use the scope attribute defined by the signal event:
<signal id="alertSignal" name="alert" activiti:scope"processInstance"/ >
Copy the code

By default, the scope property is global

Signal event instance
  • Different processes interact using signals:
  • The process starts when insurance rules are updated or changed. When a change is processed by an actor, a signal is emitted to notify the rule change:

This event is captured by all relevant process instances

  • Subscribe to a process instance of this event:

  • Signal events are broadcast to all active processors
  • In the example above, all process instances receive this event, which is what we want.
  • However, in some cases this broadcast behavior is not desired, consider the following flow:

Activiti does not support the patterns described in the process above. The idea is:

  • An error occurred when performing the [do something] task
  • Caught by a boundary error event
  • Signals are then propagated to branches on the concurrent path
  • Then interrupt [do something inparallel]
  • Activiti is running as expected so far. The signal is propagated to the boundary event and interrupts the task. However, depending on the broadcast meaning of the signal, it is also propagated to all other process instances that subscribe to the signal event. So, that’s not what we want
  • = =Note:= =
    • Signaling events do not perform any association with a particular process instance
    • If you want to send only one message to a specified process instance, you need to manually associate the message and use signalEventReceived(String signalName, String executionId) and the corresponding query mechanism

Message Event Definition

  • Message events refer to a named message, each with a name and content
  • Message events are always sent directly to a recipient
  • Message event definitions use the messageEventDefinition element. The messageRef attribute references a message child under the Definitions root node:
<! -- Process example using two message events, the start event and the intermediate capture event declare and reference two message events respectively -->
<definitions id="definitions"
  xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:activiti="http://activiti.org/bpmn"
  targetNamespace="Examples"
  xmlns:tns="Examples">

  <message id="newInvoice" name="newInvoiceMessage" />
  <message id="payment" name="paymentMessage" />

  <process id="invoiceProcess">

    <startEvent id="messageStart" >
        <messageEventDefinition messageRef="newInvoice" />
    </startEvent>.<intermediateCatchEvent id="paymentEvt" >
        <messageEventDefinition messageRef="payment" />
    </intermediateCatchEvent>.</process>

</definitions>
Copy the code
Trigger message event
  • As an embedded process engine, Activiti can’t really receive a message
    • These are environment-specific, platform-specific activities: such as connecting to JMS(Java messaging service) queues or topics or executing WebService or REST requests. The reception of this message is something you implement at one layer of your application or architecture, where the process engine is embedded
  • After an application receives a message, it must decide what to do with it:
  • If the message should trigger the start of a new process instance, execute one of the following RuntimeService methods:
ProcessInstance startProcessInstanceByMessage(String messageName);
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object> processVariables);  
Copy the code

These methods allow the use of corresponding message system process instances

  • If the message needs to be processed by a running process instance:
    • The first step is to find the corresponding process instance based on the message
    • The waiting process is then triggered
  • RuntimeService provides subscriptions that trigger the process to continue execution based on message events:
void messageEventReceived(String messageName, String executionId);
void messageEventReceived(String messageName, String executionId, HashMap<String, Object> processVariables);   
Copy the code
Query message event subscriptions
  • Activiti supports start message events and intermediate message events
  • Message start Event: The message event subscription is assigned to a specific Process Definition. This message subscription can be queried using ProcessDefinitionQuery
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
      .messageEventSubscription("newCallCenterBooking")
      .singleResult();
Copy the code

Because only one process can define a subscription point associated with a 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 is subscribed to the message event

  • Intermediate capture message events: A message event subscription is assigned to a particular execution. This message event subscription can be queried using ExecutionQuery:
Execution execution = runtimeService.createExecutionQuery()
      .messageEventSubscriptionName("paymentReceived")
      .variableValueEquals("orderId", message.getOrderId())
      .singleResult();
Copy the code

This query can invoke the corresponding query, usually process-related information: there can be at most one process instance corresponding to the orderId

Message event instance
  • Example of a process started with two different messages:

  • Message events can be used when the process needs a different way to distinguish the event that starts and ends up on the same path

Start event

  • The start event is used to indicate where the process begins
  • Type of start event (is the process started when it receives the event, or at the specified time…) , defines how the process is started, which is shown by different small diagrams in the event. In XML, these types are distinguished by declaring different child elements
  • Start events are capture events: eventually they wait until the appropriate trigger occurs
  • In the start event, you can set activiti specific properties:
    • Initiator: Saves the currently logged user to the specified variable name when the process starts:
    <startEvent id="request" activiti:initiator="initiator" />
    Copy the code
    • Login user must use IdentityService. SetAuthenticatedUserId Settings (String) method, and contained in the try – finally code:
 try {
 identityService.setAuthenticatedUserId("bono");
 runtimeService.startProcessInstanceByKey("someProcessKey");
} finally {
 identityService.setAuthenticatedUserId(null);
}
Copy the code

Null start event

describe
  • A null-start event technically means that no trigger condition is specified to start the process instance
  • Can the engine not predict when the process instance will start
  • Empty start event for: when a process instance via API startup Settings, through call startProcessInstanceByXXX method
  • Each subprocess has a null start event
ProcessInstance processInstance = runtimeService.startProcessInstanceByXXX();
Copy the code
Graphic tag
  • Empty start events are displayed as a circle. There are no internal diagrams, that is, no trigger types

XML structure
  • The XML structure of an empty start event is a normal start event definition without any child elements
  • All other start event types have a child element to declare their type
<startEvent id="start" name="my start event" />
Copy the code
Custom extension of null start events
  • FormKey: Refers to the form template that the user needs to fill out when starting a new process instance
<startEvent id="request" activiti:formKey="org/activiti/examples/taskforms/request.form" />
Copy the code

Timed start event

describe
  • A timed start event is used to create a process instance at a specified time: it can be used both for a process that starts only once and for a process that should start multiple times at a specified time interval
  • = = note: = =
    • Subprocesses cannot use timed start events
    • The timed start event starts counting time after the process is published
      • Don’t need to call startProcessInstanceByXXX, although also can call setup process method, but it will lead to call startProcessInstanceByXXX start process too much
    • When a new version of the process is deployed that contains a timed start event, the corresponding previous timer is deleted. This is because you generally do not want to automatically start process instances of older versions of processes
Graphic tag
  • Timed start events are displayed as a circle with a table inside:

The XML content
  • The XML content of a timed start event is a declaration of a normal start event, with a timed definition child element **
		<startEvent id="theStart">
            <timerEventDefinition>
            	<! -- The process will start 4 times, 5 minutes apart, starting at 12:13, March 11, 2011 -->
                <timeCycle>R4/2011-03-11T12:13/PT5M</timeCycle>
            </timerEventDefinition>
        </startEvent>
Copy the code
		<startEvent id="theStart">
            <timerEventDefinition>
            	<! -- The process will start once at the selected time -->
                <timeDate>2011-03-11T12:13:14</timeDate>
            </timerEventDefinition>
        </startEvent>
Copy the code

Message start event

describe
  • The message start event can start the process instance with a named message so that the correct start event can be selected using the message name
  • When publishing a process definition that contains one or more message start events:
    • The name of the message start event cannot be repeated in a given process definition:
      • A process definition cannot contain multiple message start events with the same name
      • If two or more message start events apply the same event
      • Or two or more message events reference the same message name
      • Activiti throws an exception when the process definition is published
    • The name of the message start event cannot be repeated in all published process definitions:
      • If one or more message start events reference a message with the same name
      • This message start event has been deployed to different process definitions
      • Activiti will throw an exception at publish time
    • Previously subscribed message subscriptions are cancelled when a new version of the process definition is published:
      • The event is also handled if there are no messages in the new version
  • To start the process instance, the message start event can be triggered using methods in RuntimeService:
ProcessInstance startProcessInstanceByMessage(String messageName);
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object< processVariables);
Copy the code
  • Here the messageName is the name attribute of the Message element referenced by the messageRef attribute of the messageEventDefinition
  • Consider the following factors when starting a process instance:
    • Message start events support only top-level processes, and message start events do not support embedded subprocesses
    • If there are multiple message start event process definition, runtimeService. StartProcessInstanceByMessage (…). The corresponding start event is selected
    • If the process has multiple messages defined start and an empty start events. RuntimeService. StartProcessInstanceByKey (…). And runtimeService. StartProcessInstanceById (…). A null start event is used to start the process instance
    • If there are multiple message start event process definition, but there were no empty start event, runtimeService. StartProcessInstanceByKey (…). And runtimeService. StartProcessInstanceById (…). Will throw an exception
    • If the process definition is only one start event news, runtimeService. StartProcessInstanceByKey (…). And runtimeService. StartProcessInstanceById (…). This message is used to start the process instance
    • If the process is started by a callActivity, the message start event only supports the following:
      • There is a separate empty start event in addition to the message start event
      • The process has only one message start event and no empty start event
Graphic tag
  • The message start event is a circle with a message event icon in the middle. The icon is white and unfilled to represent capture (receive) behavior

The XML content
  • The XML content of the message start event contains a messageEventDefinition child element in the normal start event:
<definitions id="definitions"
  xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:activiti="http://activiti.org/bpmn"
  targetNamespace="Examples"
  xmlns:tns="Examples">

  <message id="newInvoice" name="newInvoiceMessage" />

  <process id="invoiceProcess">

    <startEvent id="messageStart" >
        <messageEventDefinition messageRef="tns:newInvoice" />
    </startEvent>.</process>

</definitions>
Copy the code

Signal initiation event

describe
  • Signal start events can start a process instance with a named signal
    • Signals can be used within process instances to throw transaction triggers using intermediate signals
    • Can also be triggered by API (runtimService. SignalEventReceivedXXX)
    • In both cases, signalStartEvent with the same name is started in all process instances
    • In either case, you can choose to start the process instance synchronously or asynchronously
  • You must pass in signalName to the API, which is the value of the Name attribute of the Signal element and is referenced by the signalRef attribute of signalEventDefinition
Graphic tag
  • The signal start event is displayed as a circle with the signal event icon in the middle. The tag is unpopulated and represents capture (receive) behavior

XML format
  • The XML format of signalStartEvent is the standard startEvent declaration, which contains a signalEventDefinition child element
 <signal id="theSignal" name="The Signal" />

    <process id="processWithSignalStart1">
        <startEvent id="theStart">
          <signalEventDefinition id="theSignalEventDefinition" signalRef="theSignal"  />
        </startEvent>
        <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
        <userTask id="theTask" name="Task in process A" />
        <sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" />
        <endEvent id="theEnd" />
    </process>
Copy the code

False start event

describe
  • The error start event can be used to trigger an event subflow. An error start event cannot be used to start a process instance
  • Error start events are interrupt events
Graphic tag
  • The error start event is a circle that contains an error event flag. The tag is white and unfilled to represent capture (receive) behavior

The XML content
  • The XML content of the error start event is the normal start event definition, which contains an errorEventDefinition child element
<startEvent id="messageStart" >
        <errorEventDefinition errorRef="someError" />
</startEvent>
Copy the code

The end of the event

  • The end event represents the end of the process (branch)
  • End events areTriggering event:
    • The process reaches an end event, which triggers a result
    • The type of result is indicated by the black icon inside the event
    • In XML content, declared by contained child elements

Null end event

describe
  • A null-terminated event means that the thrown result is not specified when the event arrives
  • The engine simply ends the currently executing branch and does nothing else
Graphic tag
  • The null-terminated event is aThick-edged circles,No small ICONS inside (no result type)
The XML content
  • The XML content of an empty end event is a common end event definition
  • Does not contain child elements. Any closing event type will contain child elements of the declaration type
<endEvent id="end" name="my end event" />
Copy the code

Error end event

describe
  • When the process executes to the error end event, the current branch of the process terminates and throws an error
  • This error can be caught by the corresponding intermediate boundary error event. If no matching boundary error event is found, an exception is thrown
Graphic tag
  • The error end event is a standard end event – a thick-rimmed circle with an error icon inside, which is all black to indicate the trigger syntax

The XML content
  • The content of the error end event is an error event with a child element of errorEventDefinition
<endEvent id="myErrorEndEvent">
  <errorEventDefinition errorRef="myError" />
</endEvent>
Copy the code
  • The errorRef attribute refers to the error element defined outside the process:
<error id="myError" errorCode="123" />.<process id="myProcess">.Copy the code
  • The errorCode of error is used to find matching capture boundary error events
  • If errorRef does not match any error, errorRef is used as an abbreviation for errorCode. This is the specific abbreviation for Activiti:
<error id="myError" errorCode="error123" />.<process id="myProcess">.<endEvent id="myErrorEndEvent">
    <errorEventDefinition errorRef="myError" />
  </endEvent>
Copy the code

Is equivalent to

<endEvent id="myErrorEndEvent">
  <errorEventDefinition errorRef="error123" />
</endEvent>
Copy the code
  • Note that errorRef must conform to the BPMN 2.0 format and must be a valid QName

Cancel end event

describe
  • Cancel-end events can only be used in conjunction with BPMN transaction subprocesses
  • When a cancellation end event is reached, a cancellation event is thrown, which must be caught by the cancellation boundary event
  • Canceling the boundary event cancels the transaction and triggers the compensation mechanism
Graphic tag
  • The cancel end event is displayed as the standard end event – a thick-rimmed circle, containing a cancel icon. The cancel icon is all black, indicating the trigger syntax

The XML content
  • The cancel End event content is an end event that contains the cancelEventDefinition child element
<endEvent id="myCancelEndEvent">
  <cancelEventDefinition />
</endEvent>
Copy the code

The border incident

  • Boundary events are capture events that are attached to a link
  • A boundary event is a catch event that cannot be triggered:
    • When the node is running, events listen for the corresponding trigger type
    • When the event is captured, the node breaks and subsequent wires of the event are performed
  • Boundary events are defined the same way:
<boundaryEvent id="myBoundaryEvent" attachedToRef="theActivity">
      <XXXEventDefinition/>
</boundaryEvent>
Copy the code
  • Boundary events are defined as follows:
    • Unique identifier: process scope
    • For nodes that reference events using the Caught attribute, note that boundary events are at the same level as the nodes to which they are attached: for example, boundary events are not contained within the node
    • XML child elements of the format XXXEventDefinition (for example,TimerEventDefinition, ErrorEventDefinition…) Defines the types of boundary events

Timed boundary event

describe
  • A timed boundary event is a clock that pauses for a warning
  • A timer is started when the process reaches the segment bound to the boundary event
  • When the timer fires (within a certain amount of time), the link breaks and continues along the outgoing line of the timed boundary event
Graphic tag
  • A timed boundary event is a standard boundary event (a circle on the boundary) with a timer small icon inside

The XML content
  • The timer boundary task definition is a standard boundary event, and the child element of the specified type is the timerEventDefinition element
<boundaryEvent id="escalationTimer" cancelActivity="true" attachedToRef="firstLineSupport">
   <timerEventDefinition>
    <timeDuration>PT4H</timeDuration>
  </timerEventDefinition>
</boundaryEvent>
Copy the code
  • In a flowchart, the circles are dotted:

  • Classic application scenarios:Send notification emails without interrupting normal flow
    • There is a difference between interrupt and non-interrupt events
      • The default is an interrupt event
      • In the case of a non-breaking event, the original link is not broken, and that link remains in place
      • Accordingly, a new branch is created and execution continues along the flow of events. In the XML content, set the cancelActivity attribute to false
      <boundaryEvent id="escalationTimer" cancelActivity="false" attachedToRef="firstLineSupport"/>
      Copy the code
  • = =Note:== boundary timed events can only be performed onWhen the Job executor is enableduse
    • For example, if you set jobExecutorActivate in activiti.cfg. XML to true, the job executor is disabled by default
The problem of boundary events
  • Synchronization problem: there cannot be multiple outgoing lines following a boundary event
  • The solution to this problem is to use a concurrent gateway after a connection

Error boundary event

describe
  • Error boundary events: Intermediate catch error events at node boundaries that catch errors thrown at node scope
  • Defines a boundary error event, mostly forInline subprocessesorCall node
    • In the case of a subprocess, it creates a scope for all internal nodes
    • Errors are thrown by error – ending events. This error is passed to the upper scope until an error event definition matching the boundary error event is found
  • When an error event is caught, the bounded task bound node is destroyed, as well as all execution branches within it (synchronous nodes, inline subprocesses…). . Process execution continues along the outgoing line of the boundary event
Graphic tag
  • The error boundary event appears as a normal intermediate event (a circle with a small circle inside it) placed on the node’s tag, with a small error icon inside. The error little icon is white, indicating that it is a capture event

The XML content
  • Boundary error events are defined as ordinary boundary events:
<boundaryEvent id="catchError" attachedToRef="mySubProcess">
  <errorEventDefinition errorRef="myError"/>
</boundaryEvent>
Copy the code
  • As with the error-ending event, the errorRef references an error definition outside the process element
<error id="myError" errorCode="123" />.<process id="myProcess">.Copy the code
  • errorCodeTo match caught errors:
    • If errorRef is not set, boundary error events will catch all error events regardless of the error errorCode
    • If errorRef is set and an existing error is referenced, the boundary event catches only the error with the same error code
    • If errorRef is set but no errors are defined in BPMN 2.0,errorRef is used as errorCode
Error boundary event instance
  • How do I end a process instance of an event with an error
    • When the user task of auditing monetization is completed, an error is thrown if sufficient information is not provided
    • Errors are caught in the boundary tasks of the process, all nodes in the review sales subprocess are destroyed, even if the review customer ratio has not been completed, and a user task is created that provides more information

Signal boundary event

describe
  • A signal captured in the middle of a node boundary will be captured with the same signal name referenced by the signal definition
  • Unlike other events (such as boundary error events), boundary signal events capture more than just the bound azimuth signal. Signaling events are a global scope (broadcast semantics), meaning that signals can be fired anywhere, even in different process instances
  • Unlike other events (such as boundary error events), the propagation of the signal is not stopped once it is captured. If there are two signal boundary events, both signal boundary events will be fired if the same signal event is captured, even in different process instances
Graphic tag
  • The boundary signal event is shown as a normal intermediate event (circle with a small circle) located at the edge of the node with a small signal icon inside. The signal icon is white (unfilled) to indicate capture

The XML content
  • Boundary signal events are defined as ordinary boundary events:
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
          <signalEventDefinition signalRef="alertSignal"/>
</boundaryEvent>
Copy the code

Message boundary event

describe
  • An intermediate capture message on a node boundary catches a message with the same message name based on the referenced message definition
Graphic tag
  • The boundary message event appears as a normal intermediate event (a circle with a small circle inside it) at the edge of the node with a small message icon inside. The message icon is white (no padding) to indicate capture

  • == Note: the == boundary message event may be non-interruptive (left) or interruptive (right)
The XML content
  • Boundary message events are defined as standard boundary events
<boundaryEvent id="boundary" attachedToRef="task" cancelActivity="true">
          <messageEventDefinition messageRef="newCustomerMessage"/>
</boundaryEvent>
Copy the code

Cancellation of boundary events

describe
  • Catch cancellation in the middle at the boundary of the transaction subroutine
  • Triggered when the transaction is cancelled, when the cancellation boundary event is triggered:
    • First, all execution of the current scope is interrupted
    • It then starts compensating for all active compensation boundary events within the transaction. Compensation is executed synchronously: the boundary transaction waits for compensation to complete before leaving the transaction
    • When compensation is complete, the transaction subprocess continues along the outgoing line of the cancelled boundary transaction
  • = =Note:= =
    • There can only be one cancellation bound event per transaction subprocess
    • If the transaction subprocess contains an embedded subprocess, compensation will only trigger the subprocess that has successfully completed
    • If the transaction subprocess corresponding to the cancellation bounded subprocess is configured to be multi-instance, if cancellation is triggered by one instance, all instances are canceled
Graphic tag
  • The cancel edge event is displayed as a normal intermediate event (circle with small circle inside), with a cancel small icon inside the edge of the node. The cancel icon is white (no padding), indicating capture

The XML content
  • A cancelled boundary event is defined as an ordinary boundary event
<boundaryEvent id="boundary" attachedToRef="transaction" >
          <cancelEventDefinition />
</boundaryEvent>
Copy the code
  • The cancelActivity attribute is not required because the cancelActivity event is interrupted

Compensating boundary event

describe
  • Intermediate capture compensation for node boundaries
  • The compensation handler used to set up a node
  • A compensation boundary event must be set to a unique compensation handler using a direct reference
  • The strategy of compensating boundary events is different from other boundary events:
    • Other boundary events (signal boundary events) are activated when they reach the associated node. When you leave the node, it is suspended and the corresponding event subscription is cancelled
    • Compensation boundary events are activated when the associated node completes successfully, and the event subscription is deleted when the compensation event is triggered or the corresponding process instance terminates
  • Compensation for boundary events follows the following rules:
    • When compensation is triggered, the compensation handler corresponding to the compensation boundary event is called the same number of times, based on the number of successes of its corresponding node
    • If a compensation boundary event is associated with a multi-instance node, the compensation event subscribes to each instance
    • If the node associated with a compensation boundary event contains a loop, the compensation event is subscribed each time the node executes
    • If the process instance ends, the subscribed compensation event ends
  • Compensation boundary events do not support inline subprocesses
Graphic tag
  • The compensation boundary event is shown as a standard intermediate event (circle within circle) at the edge of the node with a small compensation icon inside. The compensation icon is white (no padding) to indicate capture
  • The following figure illustrates setting up compensation handlers for boundary events using directionless associations:

The XML content
  • Compensating boundary events are defined as standard boundary events
<boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" >
          <compensateEventDefinition />
</boundaryEvent>

<association associationDirection="One" id="a1"  sourceRef="compensateBookHotelEvt" targetRef="undoBookHotel" />

<serviceTask id="undoBookHotel" isForCompensation="true" activiti:class="..." />
Copy the code
  • Compensation boundary events are activated after the node completes successfully and the cancelActivity attribute is not supported

Intermediate capture event

  • All intermediate capture events are defined in the same way:
<intermediateCatchEvent id="myIntermediateCatchEvent" >
      <XXXEventDefinition/>
</intermediateCatchEvent>
Copy the code
  • Intermediate capture event definition:
    • Unique identifier (process-wide)
    • An XML child element (TimerEventDefinition) with the structure XXXEventDefinition defines the type of intermediate captured event

Timing intermediate capture events

describe
  • Timed intermediate events act as a listener
  • When execution reaches the capture event node, a timer is started. When the timer fires (for example, after a certain amount of time), the process continues along the outgoing node of the timed intermediate event
Graphic tag
  • Intermediate timer events are displayed as standard intermediate capture events, with a small timer icon inside:

The XML content
  • Intermediate timer events are defined as standard intermediate capture events. Specify that the child element of the type is the timerEventDefinition element
		<intermediateCatchEvent id="timer">
            <timerEventDefinition>
                <timeDuration>PT5M</timeDuration>
            </timerEventDefinition>
        </intermediateCatchEvent>
Copy the code

The event is captured in the middle of the signal

  • The intermediate capture signal event captures signals with the same signal name by referring to the signal definition
  • Signal capture events differ from other events (such as error events) :
    • Signals are not consumed after capture
    • If there are two active signal boundary events capturing the same signal event, both are fired, even in different process instances

Graphic tag

  • The intermediate signal capture event is displayed as a normal intermediate event (circle within circle) with a small signal icon inside. The signal small icon is white (no padding), indicating capture

The XML content
  • Signal intermediate events are defined as ordinary intermediate capture events. The child element of the corresponding type is the signalEventDefinition element
<intermediateCatchEvent id="signal">
        <signalEventDefinition signalRef="newCustomerSignal" />
</intermediateCatchEvent>
Copy the code

Events are captured in the middle of the message

describe
  • Catch message events in the middle, catch messages with specific names
Graphic tag
  • An intermediate capture message event is displayed as a normal intermediate event (circle within circle) with a small message icon inside. The message icon is white (no padding) to indicate capture

The XML content
  • Message intermediate events are defined as standard intermediate capture events. The child element of the specified type is the messageEventDefinition element
<intermediateCatchEvent id="message">
        <messageEventDefinition signalRef="newCustomerMessage" />
</intermediateCatchEvent>
Copy the code

Internally triggered event

  • All internally triggered events are defined the same way:
<intermediateThrowEvent id="myIntermediateThrowEvent" >
      <XXXEventDefinition/>
</intermediateThrowEvent>
Copy the code
  • Internal trigger event definitions include:
    • Unique identification (process scope)
    • Use XML child elements of format XXXEventDefinition, such as signalEventDefinition, to define the type of intermediate triggered events
A null event is triggered in the middle
  • Flowchart of an in-air trigger event, used to represent a state in a process

  • You can add execution listeners:
<intermediateThrowEvent id="noneEvent">
  <extensionElements>
    <activiti:executionListener class="org.activiti.engine.test.bpmn.event.IntermediateNoneEventTest$MyExecutionListener" event="start" />
  </extensionElements>
</intermediateThrowEvent>
Copy the code
  • You can add your own code, send the event to BAM tools or DWAH. The engine doesn’t do anything for the event, it just goes through

Signal trigger event

describe
  • The signal intermediate trigger event throws a signal event for the defined signal
  • In Activiti, the signal willradioTo all active processors. Signal can bePublish synchronously and asynchronously
    • By default, signals are sent synchronously:
      • Process instances that throw events wait until the signal is sent to all capturing process instances before continuing execution
      • Capturing a process instance is also executed in the same transaction that triggered the process instance
      • If a listening process has a technical problem (throwing an exception), all related instances will fail
    • Signals can also be sent asynchronously:
      • Determines which processors are active after the throw signal event is reached
      • For these active processors, an asynchronous reminder message (task) is saved and sent to jobExecutor
Graphic tag
  • The intermediate signal trigger event is displayed as the ordinary intermediate event (circle within circle), and there is a small signal icon inside. The signal icon is black (with padding), indicating the meaning of trigger

The XML content
  • Intermediate message events are defined as standard intermediate trigger events. The child element of the specified type is the signalEventDefinition element
<intermediateThrowEvent id="signal">
        <signalEventDefinition signalRef="newCustomerSignal" />
</intermediateThrowEvent>
Copy the code
  • Asynchronous signal events are as follows:
<intermediateThrowEvent id="signal">
        <signalEventDefinition signalRef="newCustomerSignal" activiti:async="true" />
</intermediateThrowEvent>
Copy the code

Compensates for intermediate trigger events

describe
  • Used to trigger compensation
  • Trigger compensation:
    • Compensation can be triggered by a specific node or by a scope that contains compensation events
    • Compensation is made by assigning toCompensation handler for a nodeTo complete the
      • When compensation is triggered by a node, the corresponding compensation processor executes the same number of times as the node successfully completes
      • If compensation is triggered by the current scope, compensation is performed on all nodes of the current scope, including concurrent branches
      • The trigger for compensation is inherited:
        • If the node performing compensation is a subprocess, compensation is applied to all nodes contained in the subprocess
        • Compensation is triggered recursively if the subprocess is an embedded node
        • Compensation does not propagate to the upper levels of the process
        • If compensation is triggered in a subprocess, it is not propagated outside the scope of the subprocess
        • The BPMN specification defines that a process triggered by a node only acts at the same level as a subprocess
      • Activiti performs compensation in reverse order of process execution: the last node to complete performs compensation first
      • A compensation intermediate trigger event can be used to compensate for the successful completion of a transaction subroutine
  • = =Note:= =
    • If compensation is triggered by a scope containing a subprocess that also contains the node associated with the compensation handler, compensation is propagated only to the subprocess if it has completed successfully
    • If the nodes in the subprocess also complete and are associated with a compensation handler, the compensation handler will not be executed if those nodes contained in the subprocess have not completed

In this process, we have two concurrent branches, one for embedded subprocesses and one for using credit card nodes. Assume that both branches are started, with the first branch waiting for the user to complete the scheduled audit task. The second branch executes using the credit card node and an error occurs, which causes a cancellation event and triggers compensation. At this point, the parallel subprocess has not finished, meaning that the compensation event will not be propagated to the subprocess, so the cancellation of the hotel reservation will not be executed by the compensation handler. If the user task (that is, the embedded subprocess) completes before unscheduled, compensation is propagated to the embedded subprocess

  • Process variables:
    • When compensation is embedded in a subprocess, the branch used to execute the compensation handler can access the local process instance of the subprocess, since that is the branch where the subprocess completes
    • To achieve this functionality, the snapshot assignment of process variables to branches (branches created to execute subprocesses) has the following constraints:
      • The compensation handler cannot access variables created within the subprocess that are added to the synchronous branch
      • Process variables assigned to branches are at the top of the inheritance relationship (process variables assigned to process instances are not included in the snapshot): Compensation handlers access these process variables from where they are when compensation is triggered
      • Variable snapshot is only used for nested subprocesses, not for other nodes
Known limitations: 1. WaitForCompletion ="false" is not yet supported. When compensation is triggered using an intermediate trigger compensation event, the event does not wait. 2. Compensation itself is performed by the concurrent branch. Concurrent branches are executed in reverse order of completion of the compensated node. In the future activiti may support the option to perform compensation sequentially 3. Compensation is not propagated to subprocess instances of callActivity callsCopy the code
Graphic tag
  • Intermediate compensation trigger events are displayed as standard intermediate events (circles within circles) with a small compensation icon inside. The compensation icon is black (with padding) to indicate the trigger

The XML content
  • Compensation intermediate events are defined as ordinary intermediate triggering events. Corresponding to the type of child elements is compensateEventDefinition element
<intermediateThrowEvent id="throwCompensation">
        <compensateEventDefinition />
</intermediateThrowEvent>
Copy the code
  • The optional parameter activityRef can be used to trigger compensation for a specific scope/node
<intermediateThrowEvent id="throwCompensation">
        <compensateEventDefinition activityRef="bookHotel" />
</intermediateThrowEvent>
Copy the code