Friday, May 16, 2014

To Pull or to Push

In a recent project various designs were discussed to integrate business processes implemented in Oracle BPM with a Java front-end application. More specifically, how status changes in these processes could be communicated to the end user via the front-end. The possible scenarios quickly boiled down to a poll versus push approach and various in-between scenarios. This blog lists the various approaches and design considerations.

Case

The custom-built Java application provides a thin and stateless User Interface that is used by local branch employees to sell products to customers. The process of selling these products is coordinated through a business process that is implemented in Oracle BPM 11g. The configuration of the products for a particular customer is done by the employee through the Java application. After the configuration of the product is completed, the Java application sends a signal to the process. The process will initiate various automated tasks such as credit checking. In the meantime the employee waits until these tasks are executed, then views the results of those checks and continues with the completion of the order.

The question we discussed is how to inform the employee, though the Java application, that the checks are executed by the process and the employee can move on. We know the milestone in the process is reached through a combination of the occurrence of a particular Human Task and the process state itself.

Solution based on polling

In a polling approach, the Java front-end application polls for the process status and workflow status every few seconds using the out-of-the-box Oracle BPM and Human Workflow APIs. The client applications poll to see if process instances have reached a particular milestone; if so the application moves forward. Since the Java application is stateless and has no server side, the custom application directly polls from every client session and not from a central web server. This means every new client will increase the load on the BPM platform. Stress tests showed that in this scenario the OBPM engine would be mostly busy handling polling requests and couldn’t accommodate for a high degree of concurrently running process instances.

The basic polling approach is simple to implement from the perspective of the Java front-end, but not very scalable.

We could consider optimizing the polling. For example to use a Coherence Grid or Service Bus Result Cache as caching layer between the Java clients and the Oracle BPM APIs and have the clients poll the cache instead of the APIs directly. Upside is that such a cache is easily created and that we limit the number of requests on the backend BPM engine by centralizing the polling requests and using a default caching mechanism. Downside is that the polling results can be outdated when the actual process state has changed and the process status data in the cache is not yet invalidated.

Solution based on pushing

The Java front-end clients are interested in some status change. For this purpose, a natural approach would be to push an event from the process to the Java clients when that particular milestone is reached. The preferred choice in this scenario would be to use JMS for this since this standard is both supported by Java as well as Oracle BPM 11g through the use of JCA Adapters. The pro of this approach is that it is much more scalable. We only perform an activity (publish an event) when needed, we don’t do useless polling. Downside however in this case is that the front-end application doesn’t support event subscription using JMS and this would require a significant change in that application.

Approach

We used a three step approach:

Short-term. Expose a new service that encapsulates the polling logic. Implement this service on the Service Bus and use Result Caching to cache the polling results. This service is easily created and alleviates the back-end usage of OBPM APIs. The business needs to accept that results can be outdated in some scenarios as a trade-off for the increased load that can be supported.

Middle-term. Push events from the BPM process using Mediator and a JCA JMS Adapter when a certain milestone is reached and store the event data in a custom table. Have the Java front-end poll on the custom table. In this approach the process uses events, which is the desired approach. We only need a small change to the Java front-end to poll on the custom table instead of the OBPM engine itself, thereby offloading the engine. The Java front-end however still incurs overhead by using a polling approach.

Long-term. Change the custom Java application to support event subscription, for example using JMS. This way the scalability of the front-end application will improve since the number of events is much lower than the number of polling requests. Also, on average the front-end application knows about reaching the milestone faster using events, than it does when periodically polling for that information.