I’m pretty well known for carrying everything I think I need on a project in my backpack. I carry dry erase markers, an extension cord, several thumb drives (I’m always losing them), a network cable and even beef jerky to survive the meal deficient flights. To paraphrase the comedian George Carlin - I simply feel more comfortable carrying all my stuff everywhere I go.
On a recent Oracle BPM project, I noticed that a customer adhered to a similar philosophy. While I’m a fan of having a single BPM Object instance variable store the work item instance’s information throughout the life of the process, having this object store everything including a Swiss army knife is going a bit overboard. You should suspect that you’ve got too much stuff when your instance variable uses a BPM Object that has over two groups or there are a hundred attributes.
Here’s an example of too much stuff. A healthcare company might have a work item instance in a process that involves a patient. At one step in the process, the patient’s medical history needs to be looked up. Instead of storing just the just the basic patient information (e.g. patient name or patient id, name, date of birth), 30 years of medical history is now stored with the work item. One argument I hear for carrying the patient’s entire medical history is that the time required to re-read the information downstream in the process using a web service or database is too high. What the developer does not realize is that they have put their project and Oracle BPM engine at risk by doing this and that there is a simple fix.
The “too much stuff” syndrome quickly degrades the Oracle BPM engine’s performance once in Production. You only have so much memory on any machine or VM environment. To work around the problem when testing, a developer will sometimes bump their engine’s maximum instance size setting from 16kb to 1024kb to accommodate the bloated instances flowing through their processes. The problem multiplies when you’re using either Split or Multiple activities, every copy generated by these automatically produces duplicates of the memory sucking bloated instances. Once deployed to production, the engine will quickly tire from all the stuff you’re making it carry.
Here are a few simple recommendations that project managers and developers should follow:
- Code Review - Early in the project, conduct a code review that includes a review of the primary instance variable used throughout the process.
- Use an Outside Database - Many times an outside database should instead be used to persistently store the information instead of the Oracle BPM engine’s database. The megabyte of information stored in the instance variable does not need to be read in every activity of the process and the information is not updated in every activity of the process. Oracle BPM assumes, however, that this is the case with normal instance variables - your instance megabyte is read from and written to the engine’s database at the beginning and end of each activity’s execution even if it is not displayed or updated. If you instead store the id in the instance variable, this id could be used to easily and quickly read or update the information in the outside database when necessary. The bottom line is to not treat your instance variable as the database of record. Use an outside database for this.
- Throttle Down the Engine's Maximum Instance Size - Strive to keep the maximum instance size setting on the Engine throttled down to 128 or 256kb. Keep this setting the same for your DEV, QA / UAT and PROD Oracle BPM engines. Projects deployed to these engines will be caught immediately.
- Use Separated Instance Variables - Instance variables have a property called “Category”. As you are creating Instance variables, you usually leave the category set to the default - “Normal”. If you feel it is necessary to store large BPM Objects in an instance variable (again – all your stuff), always set the instance variable’s category property to “Separated”. Although there is no easy way to detect the size of an instance variable, if you believe the instance variable will store a large amount of information (10 Kb or more) go ahead and mark it as separated. As the name implies, during runtime Oracle BPM automatically stores these variables separately in the database to avoid performance problems. They are only read when the instance needs to either display their value in the activity. They are only written back to the Engine’s separated instance table when the information has been changed inside the activity. This differs from the normal instance variable’s behavior where normal instance variables are always read and written to the engine's database.
- Set Unneeded Variables to Null - Inside a Multiple activity always set the copy’s unneeded instance variables and attributes to null. This will cause the copies of the instance generated to consume less memory than the original work item instance.