Previously, we discussed the Fork and Join shape and the possibilities of flows that run parallel to one another.What we did not discuss are the rules that you have to obey so your flows make it through the compile phase. A quick recap: the Fork lets you split a single stream into a maximum of 64 concurrent flows. This is more than enough—why? Try putting 64 concurrent flows on one page! The Join brings the concurrent flows back together and can do this in two ways:
■ AND The Join waits for all concurrent flows to finish before continuing the flow.
■ OR The Join waits for the first concurrent flow to reach the Join before continuing.The other flows will finish.
To make a concurrency successful, the schedule needs to conform to the following guidelines:
■ Only flows that originated from the same Fork can come together in a Join. Figure 7.37 shows a valid Fork-Join construction, and Figure 7.38 shows an invalid Fork-Join construction.
■ A flow that originates from a Fork must end in a Join or an End shape.
■ Concurrent flows are not allowed to communicate or share messages with each other.
■ Flows entering an OR-Join can have no more than one action.
■ Concurrent flows can contain Decision and While flows.
■ Concurrent flows can contain transactions, and a transaction can hold a Fork-Join construct.
■ Concurrent flows that enter an OR-Join are not allowed to have more than one action.
Figure 7.37 A Valid Join-Fork Construction
Figure 7.37 A Valid Join-Fork Construction
■ The flow exiting the OR-Join is not allowed to make use of data that becomes available through an action in one of the concurrent flows. This is to prevent a situation where the data is not available at the time the main flow reaches that action.
As you can see from these guidelines, the OR-Join is far more restrictive than the AND-Join. The reason for this is technical, and related to the way it is imple-mented.What it comes down to is that the OR is not a real synchronization point, and the AND is.Therefore, the schedule loses control of the "pending" concurrent flows, while the main flow finds it way to the end. However, the XLANG schedule can only finish if all concurrent flows finish. In a way, they can hold the schedule hostage from exiting and releasing its resources. Since the business flow is finished, it cannot be dehydrated. This would be a classic example of "memory leakage.'The compiler wants to be positive that the design of the business process does not create such a situation. Remember, you do not have this problem with the AND-Join; since the business process is stuck at this Join, and the Schedule will not finish, you will notice right away you have a problem.
Instead of relying on the compiler, try to think ahead when designing concurrent flows. First, use an OR-Join only in situations where the business flow can benefit from it, by improving performance. Second, determine under which circumstances a concurrent flow can be delayed (indefinitely).Third, prevent these situations from happening; for example, if you are not sure when a synchronous method call will return, place it in a timed transaction so you are sure it will be aborted if things take too long. Another example: if an action waits, in a Receive, for a message or method call, use the wait period to curtail the waiting.
The last question that remains is when to use the OR-Join and when to use the AND-Join? You will use concurrent actions to speed the execution of the business process, by doing actions at the same time independently from one another. Let's look at an example. A request comes in to open a bank account. Before this can be done, the data in the request has to be checked against different data sources; for example, "is the requester already a customer," "can the provided address information be correlated," and "is this person blacklisted?" When these answers are in, the business flow can make a decision. This is an example of an AND-Join, since the flow can only proceed if all the information is collected. An Or-Join can be used in a situation where the business flow has to perform an action if at least one of a number of actions is performed. For example, the request for a new bank account is authorized; therefore, the customer data has to be saved in the main customer database and the branch office database. This is done since these databases are only synchronized during the weekends. Therefore, it is sufficient that this information is saved in at least one database before continuing the business flow.
The Fork itself can be used if there are some spin-off actions that have to be performed. For example, after the customer information is saved in at least one database, a welcome package has to be sent to the customer, and the branch office gets an e-mail informing them of the new customer. These spin-off actions can be done independently from the main flow and are therefore forked.
Was this article helpful?