4.2. Process Patterns and the P4The process community has taken a similar approach by identifying and codifying its own set of common problems. The article "Workflow Patterns" by van der Aalst, ter Hofstede, Kiepuszewski, and Barriosa group referred to in this chapter as the "Process Four," or P4lists and describes 20 patterns specific to processes.[*] The P4 catalog is a comprehensive account of patterns for process control flow. The benefit of control flow patterns is to help the process designer determine different ways to assemble activities (for example, how to implement conditional logic based on a deferred choice).
Whereas GoF patterns are documented as object models and code recipes, P4 patterns are inherently spatial and visual: a process pattern is a cluster, or constellation, of process activities arranged in just the right way to solve a difficult problem. The process patterns read like a wish list for a process notational language. Some are obvious (such as support for a sequence of activities); others are exotic (for example, multiple instances of an activity where the number of instances is not known even at runtime). NOTE Animated demonstrations of the patterns are available at the P4's Patterns website: http://www.workflowpatterns.com. This chapter is a reference guide to the 20 P4 patterns; it discusses each pattern's intent, alternative names, motivation, implementation details, and related patterns. The patterns are grouped into six main categories:
After the patterns, the chapter covers YAWL, a language proposed by the P4 to support all the patterns; provides a few patterns for areas beyond mere control flow; and concludes with a few coding recommendations.
Basic patterns cover fundamental process capabilities: running activities in a sequence; spawning, and later joining, parallel lines of execution; and branching into one of several directions based on a conditional choice. The five basic P4 patterns are: Sequence, Parallel Split, Synchronization, Exclusive Choice, and Simple Merge. SequenceThe intent of the Sequence pattern is to run activities sequentially. For example, run activity A followed by B followed by C, and so on. This pattern is also known as Sequence Flow. The need for activity sequencing is obvious: almost every process has at least one segment of two or more steps to be performed sequentially. In Figure 4-1, for example, the process of opening a bank account requires getting a manager to approve the account open application, updating the account database, and sending a welcome package to the customer. Figure 4-1. The Sequence pattern in a process for opening a bank account![]() Given that activity sequencing is an essential part of the notion of process, it is not surprising that all BPM vendors and specifications support the Sequence pattern. In BPEL, for example, the implementation of the bank account process uses the sequence activity: <sequence> <invoke name="Get approval" . . . /> <invoke name="Update account DB" . . . /> <invoke name="Send welcome package" . . ./> </sequence> This pattern is related to all other patterns. Parallel SplitThe intent of the Parallel Split pattern is to branch, or fork, from a single activity to multiple parallel paths. This pattern is also known as AND-split. Parallel split is used when multiple streams of work need to execute at roughly the same time. The example of a travel agency booking is shown in Figure 4-2: when the customer's itinerary is received (Get itinerary), the process spawns separate paths to handle the bookings for air (Book airline), hotel (Book hotel), and car (Book car). Figure 4-2. Parallel Split and Synchronization in travel agency process![]() The use of parallelism in this example is sensible, because the three streams are independent. Furthermore, if a delay occurs in any of the bookings (for example, if the hotel booking cannot complete until someone from the hotel calls a travel agent with a manual confirmation), the other bookings are unaffected. Implementations of this widely supported pattern include control constructs (such as all in BPML and flow in BPEL) and explicit split elements (such as the AND gateway in BPMN, plus the split in UML activity diagrams.) The UML activity diagram implementation is shown in Figure 4-3; the upper black bar splits Get itinerary to the three booking activities. This pattern is related to Synchronization, Exclusive Choice, Multi-Choice. SynchronizationThe intent of the Synchronization pattern is to have several parallel paths converge on a single activity, which waits for the completion of all paths before starting. The pattern is also known as AND-join. Figure 4-3. A UML activity diagram of Parallel Split and Synchronization in travel reservation![]() Synchronization, or the merging of parallel paths spawned by a parallel split, is a common requirement for many processes, such as the example shown in Figure 4-2, in which the activity Send Confirmation must not be started until the three preceding parallel activities Book air, Book hotel, and Book car have completed. In languages in which parallel processing is modeled as a control structure (such as flow in BPEL and all in BPMN), the control structure itself manages the merge; for example, when the flow in BPEL completes, its child activities are guaranteed to have completed. In languages where the merge requires an explicit join element (such as the AND gateway in BPMN and the join in UML activity diagrams, shown as the lower black bar in Figure 4-3), the join element performs the merge. The pattern is related to Parallel Split, Simple Merge, Synchronizing Merge, Multi-Merge, Discriminator. Exclusive ChoiceThe intent of the Exclusive Choice pattern is to branch from a single activity to exactly one of several paths, based on the evaluation of a condition. This pattern is also known as XOR-split. The need for exclusive choice is commonplace. Figure 4-4 shows a typical example: when a customer applies to open a bank account, if the application is approved, the customer is sent a welcome package; otherwise, the customer is sent a rejection letter. This behavior is modeled as an XOR-split from Get approval to Send welcome package or Send rejection letter. The effect is that of an if statement in the process. Implementations of this widely supported pattern include control constructs (such as switch in BPEL and BPML) and explicit split elements (such as the XOR gateway in BPMN and the diamond in UML activity diagrams). The UML implementation is shown in Figure 4-5; the diamond following from Get approval splits to Send welcome package or Send rejection letter. This pattern is related to Parallel Split, Simple Merge, Synchronizing Merge, Multi-Merge, Discriminator. Simple MergeThe intent of the Simple Merge pattern is that several exclusive conditional paths converge on a single activity, which starts executing when the one chosen path completes. The pattern is also known as XOR-join. Figure 4-4. Exclusive Choice and Simple Merge in a process opening a bank account![]() Figure 4-5. UML activity diagram for Exclusive Choice and Simple Merge in a bank account opening process![]() A simple merge is the endpointthe XOR-joinof a process split started by an exclusive choice, which might be considered in programming terms as the end of an if statement. Any process that uses conditional processing requires a simple merge. The XOR-join shown in Figure 4-4 merges the paths containing activities Send welcome package and Send rejection letter into a single path in which Record in audit trail is executed. In languages in which conditional processing is modeled as a control structure (for example, switch in BPEL and BPMN), the control structure itself manages the merge (for example, when the switch in BPEL completes, its selected case is guaranteed to have completed.) In languages in which the merge requires an explicit join element (such as the XOR gateway in BPMN and the diamond in UML activity diagrams), the join element performs the merge. In Figure 4-5, the diamond pointed to by Send welcome package and Send rejection letter is a simple merge; the subsequent Record in audit trail executes once the chosen activity completes. This pattern is related to Synchronization, Exclusive Choice, Synchronizing Merge, Multi-Merge, Discriminator.
The majority of BPM products and specifications support the basic and/or-split/join patterns described in the "Basic Patterns" section. Less well supported, but equally important, are the advanced branch and join patterns described in this section. The P4 has identified four patterns in this category: Multi-Choice, Synchronizing Merge, Multi-Merge, and the Discriminator and N-out-of-M-Join. Multi-ChoiceThe intent of the Multi-Choice pattern is to choose one or more parallel branches, in which each branch is taken only if it satisfies a particular condition. The pattern is also known as Inclusive OR-split. The Multi-Choice pattern describes the forking of a process to multiple branches where each fork is based on a condition that is known only at runtime. Multi-Choice is sometimes known as the OR-split; it differs from the Exclusive Choice pattern considered earlier, which is also known as the exclusive-OR- or XOR-split, by allowing more than one path to be spawned; exclusive choice selects exactly one direction. The P4 example, shown in Figure 4-6, describes the actions required in the aftermath of a building fire. Figure 4-6. The Multi-Choice and Synchronizing Merge patterns for a fire investigation process![]() Either the insurance company or the fire department, or both, must be contacted. The choice is based on conditions specific to the fire; the fire department is contacted if there is structural damage to the building, and the insurance company is contacted if the estimated damaged exceeds a particular dollar value. Multi-Choice is easy to represent in BPMN, as Figure 4-7 shows. Figure 4-7. The Multi-Choice and Synchronizing Merge patterns in BPMN for a fire investigation process![]() A special inclusive OR gateway symbol (a diamond with an inner circle) with outbound conditional sequence links models the behavior compactly. More work is required in the BPEL and BPML implementations. In BPML, the only viable approach is to run multiple switch activities inside of an all (that is, multiple exclusive ORs in parallel) In BPEL, the behavior can be modeled with guarded links in a flow activity. This pattern is related to Parallel Split, Exclusive Choice, Synchronizing Merge, Multi-Merge, Discriminator. Synchronizing MergeThe intent of the Synchronizing Merge pattern is to join branches spawned by a Multi-Choice. In other words, it waits for all of the active paths in a parallel structure to complete. This pattern is also known as Inclusive OR-join. Continuing the example provided in the Multi-Choice pattern, in the wake of a building fire, once all third parties have been contacted (that is, the fire department, the insurance company, or both), a report must be submitted to the company. This is depicted in Figure 4-6. The Synchronizing Merge pattern captures this scenario. Though the idea is intuitive, many BPM products lack support for this pattern because of the thorny implementation difficulties of tracking which branch was actually executed. In the fire investigation example, the requirement is that the report be submitted exactly once; but without the right conceptual model, this requirement is hard to meet. Languages that use the Petri net conception of token passing to model control flow fare well here. In BPMN, the inclusive OR gateway handles both splits and joins, as shown in Figure 4-7; the BPMN uses tokens to explain how the gateway keeps track of the active branches. BPEL uses the principle of dead path elimination , another Petri-net-inspired concept, to solve the problem. Though the activity Submit report requires only one of the Contact fire department and Contact insurance company activities to run, BPEL's control flow semantics prevent Submit report from executing until its knows the results of both. If one of these activities does not run, because its condition was not met, it passes through immediately to Submit report, as if it had run. For example, if the damage was structural but less than $1,000 in cost, Contact insurance company completes immediately, and Submit report waits for Contact fire department to execute. The mechanics of dead path elimination are examined in detail in Chapters 3 and 5. This pattern is related to Synchronization, Simple Merge, Multi-Choice, Multi-Merge, Discriminator. Multi-MergeWhere synchronizing merge waits for all incoming branches to complete before continuing, the Multi-Merge pattern allows each incoming branch to continue independently of the others, enabling multiple threads of execution through the remainder of the process. For example, when concurrent activities A and B are multi-merged into C, the possible combinations of execution are: ABCC, ACBC, BACC, and BCAC. This pattern is also known as Uncontrolled Join. Ostensibly awkward and undesirable, Multi-Merge is useful (as the P4 argue) in cases where "two or more parallel branches share the same ending".[*] The pattern facilitates common logic for those branches upon completion. In a process that permits simultaneous auditing and processing of an application, as illustrated in Figure 4-8, each independent action should be followed by a Close case activity.
Figure 4-8. The Multi-Merge pattern![]() BPMN's implementation, shown in Figure 4-9, is the simplest. Figure 4-9. The Multi-Merge pattern in BPMN![]() Because there is no join of Audit application and Process application, the process allows each to transition independently to Close case. Most other languages studied in this book, including BPEL and BPML, are stumped by this pattern, because they do not allow the same activity to be executed by separate threads. The approach shown in Figure 4-10 is a compromise: have each path run its own copy of Close case. Figure 4-10. An alternative Multi-Merge implementation![]() This pattern is related to Synchronization, Simple Merge, Synchronizing Merge, Multi-Choice, Parallel Split, Multiple Instances Without Synchronization, Discriminator. Discriminator and N-Out-of-M JoinIn the Discriminator pattern , when multiple parallel branches converge at a given join point, exactly one of the branches is allowed to continue on in the process, based on a condition evaluated at runtime; the remaining branches are blocked. Discriminator is a special case of the N-Out-of-M Join pattern, where M parallel branches meet at a point of convergence and only the first N are let through. This pattern is also known as Complex Join. The need for this pattern arises when only a subset of assigned work is required. In the 2-of-3-join example shown in Figure 4-11, to obtain a security clearance, an applicant must meet two of three conditions. Figure 4-11. 2-of-3 join for a security clearance project![]() When two of the corresponding activities complete, the activity Grant secuity clearance triggers, and the third activity is discarded. Impressively, BPMN supports these patterns out of the box. The complex gateway (diamond with interior asterisk) in Figure 4-12 is configured with special routing rules for the 2-of-3 logic. Figure 4-12. BPMN 2-of-3 join for the security clearance project![]() However, most other languages lack a clean solution. In BPEL, one approach would be to put the three activities in a flow, and, after each completes, check if another activity has already completed; if so, use the Cancel Activity pattern to cancel the third activity, thereby completing the flow with two completed activities. This pattern is related to Synchronization, Simple Merge, Synchronizing Merge, Multi-Merge, Multiple Instances with Runtime Knowledge, Multiple Instances without Runtime Knowledge.
So-called "structural " patterns are actually recipes for unstructured design practices such as GOTO-style jumps and contending termination points. However, as the P4 explain, for some processes, the use of these patterns makes the design more readable and understandable. There are two structural patterns: Arbitrary Cycles and Implicit Termination. Arbitrary CyclesThe Arbitrary Cycles pattern repeats an activity or a set of activities by cycling back to it in the process. This pattern is also known as GOTO or loop. Most process languages and vendor implementations allow only block-structured loops such as while-do or do-while, whose entry, exit, and jump-back points are defined according to rigorous proof rules. The logic of some processes, such as the loan process shown in Figure 4-13, requires the looser approach of goto. Figure 4-13. The Arbitrary Cycles pattern for a loan application![]() The loan process is designed to retry the Validate application activity not only when validation fails, but also downstream when something in the application prevents approval. This logic is difficult to model with a structured loop. BPMN supports this pattern because it permits sequence flow to connect to upstream activities. BPEL does not support the pattern: its only loop is the structured while activity, and the flow activities does not permit cycles. This pattern is related to the Multiple Instances patterns. Implicit TerminationIn most languages, a process, even if it spawns a complex tree of concurrent branches, has exactly one exit point into which all possible paths converge. The Implicit Termination pattern is a relaxation of the design rules: the process completes when the activities on each of its branches complete. Implicit Termination helps reduce clutter and complexity in a process by relaxing the restriction for a single exit point. If a process has N branches, it completes only when each of the N branches completes; there is no need to join the branches prior to completion. In Figure 4-14, for example, the process spawns multiple parallel instances of the Process record activity. ("MI no sync" is one of the Multiple Instances patterns described in the next section.) Figure 4-14. The Implicit Termination pattern![]() The desired behavior is to let the process continue until each instance completes. An explicit endpoint would necessitate complicated merge logic. BPEL's flow activity supports implicit termination because it does not require its network of activities to converge on a single exit point; the flow completes when all of its activities complete. This pattern is related to Interleaved parallel routing (but very faintly).
In the patterns discussed in this section, multiple instances of an activity run concurrently. A given language's support for these patterns requires support for the ability to spawn multiple instances, and, in three cases, the ability to perform a synchronizing merge of the branches. The four Multiple Instances (MI) patterns are: Without Synchronization, With Design-Time Knowledge, With Runtime Knowledge, and Without Runtime Knowledge. Without SynchronizationThe intent of the Without Synchronization pattern is to perform multiple concurrent instances of an activity but let each run on its own with no overall synchronization. A batch process, for example, reads a large data file record by record and spawns a subprocess to handle each record. The implementation, as suggested by the P4, is to perform a parallel split in a loop.[*] Figure 4-15 illustrates this concept.
Figure 4-15. The Multiple Instances Without Synchronization pattern![]() BPMN supports this pattern out of the box; the activity is configured to loop in multiple parallel instances (denoted by two parallel bars marked inside the activity's box) with the flow condition set to none, as shown in Figure 4-16. In BPEL, the behavior can be achieved by invoking an asynchronous process in multiple iterations of a while loop. This pattern is related to other Multiple Instances patterns, Parallel Split, Multi-Merge. Figure 4-16. The Multiple Instance Without Synchronization pattern in BPMN![]() With Design-Time KnowledgeThe intent of the With Design-Time Knowledge pattern is to perform N multiple concurrent instances of an activity, where N is a constant at runtime. In addition, it joins these instances before continuing with the remainder of the process. This pattern is similar to a basic AND-split and -join, except that the activity to be performed is always the same type. In the requisition process in Figure 4-17, exactly three authorizations are required; each is performed in parallel but needs to be merged with the others before the requisition can continue. Figure 4-17. The Multiple Instances With Design-Time Knowledge pattern for authorizations![]() In BPMN, this requisition activity is configured to loop in multiple parallel instances with the flow condition set to all, as shown in Figure 4-18. In BPEL, the easiest approach is to place the three requisition activities in a flow activity. Figure 4-18. BPMN implementation of the Multiple Instances With Design-Time Knowledge pattern for authorizations![]() This pattern is related to other Multiple Instances patterns, Parallel Split, Synchronization. With Runtime KnowledgeThe intent of the With Runtime Knowledge pattern is to perform N multiple concurrent instances of an activity, where the value of N is known at runtime before the Multiple Instances loop is started. In addition, it joins these instances before continuing with the remainder of the process. In terms of its observable execution behavior, this pattern is similar to the design-time pattern: N instances of an activity are run in parallel and synchronized. The motivation is the same in each case. The implementation, however, is far more challenging. Of the approaches described by the P4, the simplest is shown in Figure 4-19. In this example, a customer has ordered a number of books from an online store. The process must ensure the availability of each book before processing the order. Hence multiple instances of the activity Check availability are required, and the number of instances is not known until the Figure 4-19. The Multiple Instances With Runtime Knowledge pattern![]() customer has placed the order. The process implements a loop that spawns exactly the right number of Check availability instances. When each instance completes, it marks itself as done (setting a flag in a table or a process variable). The activity Check num marked done determines whether all of the instances have completed; it repeats this check in a loop before finally transitioning to the activity Process book order. None of the leading process languages has a cleaner solution than this. Implementations in BPEL, BPML, and BPMN should follow this approach. This pattern is related to other Multiple Instances patterns, Parallel Split, Synchronization. Without Runtime KnowledgeThe intent of the Without Runtime Knowledge pattern is to perform multiple concurrent instances of an activity, where the number of instances is not known until some point during the actual processing of the instances. In addition, it joins these instances before continuing with the remainder of the process. The motivation is the same as that of the two preceding synchronized Multiple Instances patterns. The fact that the number of instances to run is evaluated as late as possible in processing is an implementation consideration. A typical example occurs in the processing of an insurance claim: the number of eyewitness reports required to complete the claim varies all the way through; the stopping condition is evaluated in the loop. The implementation is similar to the case in which the number of instances is known at runtime, except the governing loop is not a for loop that indexes over the required number of instances but a while loop that on each iteration executes a task that reevaluates the number of instances required. Figure 4-20 illustrates this pattern. Figure 4-20. The Multiple Instances Not Known At Runtime pattern![]() Multiple instances of Take report are performed; the activity More reports evaluates whether to continue the loop; All reports in waits for the completion of all instances before allowing the claim to be completed. This pattern is related to other Multiple Instance patterns, Parallel Split, Synchronization.
State-based patterns apply to processes that are largely event-driven and spend most of the time waiting for an event to trigger the next activity. There are three state-based patterns: Deferred Choice, Interleaved Parallel Routing, and Milestone. Deferred ChoiceThe intent of Deferred Choice is similar to the basic Exclusive Choice pattern, in that a decision is made to follow one of multiple paths, except the decision is not made immediately but is instead deferred until an event occurs. This pattern is also known as Event Choice and Pick. Processes that are event-driven are likely to use this pattern. A very common scenario is to wait for either a positive or negative result to a request. The process, shown in Figure 4-21, is fairly common. In this example, the process is waiting for either an acceptance or rejection result to an earlier request. Each event leads to a distinct execution path: acceptance means sending a welcome package; rejection means sending a rejection letter. Though some older vendors lack support for deferred choice, as the P4 point out, most contemporary languages have explicit control structures for it. BPEL uses a pick activity to listen for exactly Figure 4-21. The Deferred Choice pattern for acceptance or rejection![]() one of several inbound service events. BPMN has a special exclusive OR gateway (the diamond with a star in the middle in Figure 4-22) for events. Figure 4-22. The BPMN implementation of the Deferred Choice pattern for acceptance or rejection![]() This pattern is related to Exclusive Choice. Interleaved Parallel RoutingThe intent of the Interleaved Parallel Routing pattern is that several activities are to be performed in sequence (not in parallel, as the name of the pattern suggests), but the order of execution is arbitrary and is not known at design time. This pattern is also known as Ad Hoc Process. Though not as prevalent as other process patterns, Interleaved Parallel Routing does occur in cases where several activities must be executed but a specific ordering is impossible. A good example is given by Dumas and ter Hofstede:[*] an applicant to the army must take three testsoptical, medical, and dentalone after the other but in any order; when the applicant completes one test, the next one to take is determined by the availability of doctors. The desired model is depicted in Figure 4-23.
A naïve implementation of this case, as shown in Figure 4-24, would contain six execution pathsone for each permutation of the three tests. The initial three-way split (optical, medical, or dental) creates three branches, each of which in turn bifurcates (that is, splits into two) to branches representing the remaining two choices; for example, the optical path splits into the medical and dental paths. The three-way split and the three two-way splits are deferred choices because they require an eventa signal that a doctor is now freeto drive the choice. Figure 4-23. The Interleave pattern![]() Figure 4-24. Naïve implementation of Interleave![]() Most BPM vendors and standards lack support for interleaved parallel routing. BPMN and BPEL, with ad hoc processes and serialized scopes, respectively, offer elegant solutions to the problem. In the BPEL solution, the process splits into parallel paths but uses a form of mutual exclusion to ensure that the paths run serially. In the following code sample, adapted from the P4's pattern analysis of BPEL,[*] the BPEL flow construct runs the scope activities optical, dental, and medical in parallel:
<flow> <scope name="optical" variableAccessSerializable="yes"> <sequence> write to variable C run optical activity write to variable C </sequence> </scope> <scope name="dental" variableAccessSerializable="yes"> <sequence> write to variable C run dental activity write to variable C </sequence> </scope> <scope name="medical" variableAccessSerializable="yes"> <sequence> write to variable C run medical activity write to variable C </sequence> </scope> </flow> Mutual exclusion is enforced by having each activity flag itself as variableAccessSerializable and reference a shared process variable C. While one activity is running, the others are blocked. The order of execution is unpredictable: it can take any of the six permutations of optical, dental, and medical, but each permutation runs sequentially. This pattern is related to Deferred Choice. MilestoneThe intent of the Milestone pattern is that an activity can be performed only when a certain milestone is reached and cannot be performed after the milestone expires. This pattern is quite distinctive and has no other names. The most unusual and conceptually difficult of the P4 patterns, the Milestone pattern describes the scenario in which an activity can be executed only after the occurrence of an enabling event but before the occurrence of a disabling event. The activity can be performed multiple times, in fact. For example, in an auction, a bidder can place bids at any time between the start and end of bidding. A buyer can cancel an order up until the order has been shipped. Scenarios such as this are not rare; this pattern benefits designers who face them. None of the languages considered in this book has an obvious solution. In one of the approaches described by the P4, shown in Figure 4-25, the enabling event (Open bidding) is followed by a deferred choice, with conditional paths determined by the intermediate activity (Bid) and the disabling event (Close bidding). Figure 4-25. Milestone pattern for an auction bid![]() If the intermediate activity occurs, it loops back to the deferred choice; if the disabling event fires, it starts its own path, preventing any occurrence or recurrence of the intermediate activity. In the BPEL implementation, the deferred choice is a pick activity that resides in a while loop. If the intermediate event occurs, the loop continues with another iteration; if the disabling event occurs, the loop breaks. This pattern is related to Deferred Choice.
Every process designer needs a clever strategy to cancel a process at any point during its execution. A 25-step insurance claim process, for instance, must terminate as soon as the subscriber calls to rescind the claim. The hard way to solve this problem is to add cancellation checks at each of the 25 steps; more desirable is a single check or action that covers the execution of the entire process. There are two types of cancellation patterns: Cancel Activity and Cancel Case. Cancel ActivityThe intent of the Cancel Activity pattern is to stop the execution of a particular process activity on a cancellation trigger. This pattern is also known as Kill Activity. The Cancel Activity pattern is useful to abort a long-running or suspended activity (e.g., a manual approval that has been ignored by its owner), or to reroute a process to an escalation path. The former case is shown in Figure 4-26. Figure 4-26. The Cancel Activity pattern![]() Between Step X and Step Y sits a long-running activity called Long step. To enable the cancellation of Long step during its execution, a deferred choice is established between Long step and a Cancellation event. As soon as deferred choice completes, Step Y is started, and the subsequent effects of the other activity are ignored. Figure 4-27 shows a BPMN implementation of this pattern. Figure 4-27. A BPMN implementation of the Cancel Activity pattern![]() When Step X completes, the process branches into two parallel activities: Long step and Canceller. Normally, Long step executes to completion and transitions to Step Y. But at any point during the execution of Long step, the Canceller activity can generate an exception (Cancel long step) that aborts Long step and causes it to transition immediately to Step Y. Typically the Canceller activity is event-driven: it waits, for as long as Long step is running, for a cancellation event from a user or system. This pattern is related to Cancel Case. Cancel CaseThe intent of the Cancel Case pattern is to stop the execution of an entire process on a cancellation trigger. This pattern is also known as Kill Process. Though most BPM vendors provide a means to cancel a process through their administration console, building the cancellation logic directly into the process code guarantees portability and enables more graceful handling. Figure 4-28 shows the basic shape of the pattern. Figure 4-28. The Cancel Case pattern![]() When the process is started, it splits into separate paths for the main flow and receipt of a Cancellation event. If the Cancellation event arrives while the main flow is executing, it terminates the whole process. The BPEL implementation is shown in the following code sample. At the process scope, an event handler is defined that listens for a Cancellation event; when the event arrives, the handler terminates the process: <process> <eventHandlers> <eventHandler name="cancelEvent" . . .> <terminate/> </eventHandler> </eventHandlers> <sequence> . . . <!-- main flow --> </sequence> </process> The BPMN approach is shown in Figure 4-29. The logic is similar to Cancel Activity, except that here the Canceller runs in parallel to the Main flow of the process, rather than to just a single activity. If the Canceller executes, it transitions to a stop event, which stops the entire process, regardless of the progress of the Main flow. This pattern is related to Cancel Activity. Figure 4-29. A BPMN implementation of the Cancel Case pattern![]() |