BPMN's Magic Event Type

Occasionally in my BPMN Method and Style training, a student will submit a Certification exercise containing a Conditional event. I have always rejected that. Conditional events are not part of Method and Style, and that's because I have always considered them to mean "some magic occurs". According to the spec, a Conditional event may be used either as the Start event of a process or event subprocess, a Catching Intermediate event, or a Boundary event, triggered when its Boolean expression attribute becomes true. But what data can that expression reference? This is the problem, because the spec does not say. In fact, the only place where the BPMN 2.0 spec speaks to it is in the context of a process Start event, where no instance data yet exists!

For that, it says:

This type of event is triggered when a condition such as “S&P 500 changes by more than 10% since opening”, or “Temperature above 300C” become true. The condition Expression for the Event MUST become false and then true before the Event can be triggered again. The Condition Expression of a Conditional Start Event MUST NOT refer to the data context or instance attribute of the Process (as the Process instance has not yet been created). Instead, it MAY refer to static Process attributes and states of entities in the environment. The specification of mechanisms to access such states is out of scope of the standard.
Here you should interpret the term "out of scope" to mean undefined, or to use my word, "magic."

If you were a generous sort, you might infer that for other Conditional events, the expression references the "data context", i.e. what we call process data. And it turns out that this is exactly how Trisotech has implemented Conditional events. Because non-executable processes, our focus in Method and Style, do not define process data, I will continue to avoid Conditional events there. But in Business Automation, they enable some event-triggered behaviors that are otherwise more complicated to model. Recall from previous posts that in Trisotech BPMN, process data and expressions are defined using FEEL, the Low-Code language defined in the DMN spec. The condition expression of a Conditional event is thus a FEEL Boolean expression referencing instance data. A Conditional event is triggered when the value of one or more process variables change such that the condition expression becomes true.

So when can that occur? Except for cloud datastores, which may be updated from outside the process, the value of a process variable is changed only when its incoming data association occurs, i.e. at the completion of the activity or event at the source of that connector. Thus it is always possible that Conditional event behaviors could alternatively be modeled more conventionally using gateways, sometimes in combination with Signal events. For example, suppose we have an established decision service Validate Input, but starting in 2023 we want to perform additional validations under certain conditions. We could model this using a non-interrupting Conditional event subprocess, as shown below.

However, we could model the same logic more conventionally using an OR gateway leading to a regular subprocess.

In the BPMN Method and Style training we discuss two ways a process can receive information from outside: either via a message or shared data. In Business Automation, using shared data is probably more common. If that shared data used a cloud datastore (as opposed to an external app or database), you might think you could wait for a condition on the datastore to become true. Unfortunately, the Conditional event cannot be used for this. At least on the Trisotech platform today, the datastore update must be caused by a data association from within the process, not externally. For example, the scenario below, in which a Service request process waits for payment via a separate Payment process, does not work with Conditional events. Changes to the datastore Orders are not visible to the Conditional event.

But we could put the Payment process inside our main process using a call activity, which would allow the wait-for-Condition to work:

Although one could debate the point, on balance this solution is probably better than the more conventional alternative using a Signal event thrown by Payment process.

If you are willing to have Payment process throw a Signal, throwing a Message is even simpler.

Conditional boundary events have the same basic issue. Because the condition cannot be triggered from outside the process, it must be caused by a parallel thread of execution within the process. (In the absence of parallel flow, a simple gateway testing the condition is always going to be simplest.) So again, the modeler's choice is between a Conditional boundary event testing shared process data and Signal throw-catch. And again, I believe that in this case the Conditional event solution is better.

Bottom line, while Conditional events appear useful on the surface, their utility is in practice limited to scenarios in which actions on one parallel thread of a process control actions on another thread.