Hi there AppWorks fans,
Welcome to a new installment of AppWorks tips.
For this week, an interesting topic on the agenda. It all has to do with the principles behind a dynamic enumerated property that can trigger a generated short-lived BPM with or without dependent input property. Yes, that’s a mouth-full of information in one sentence! That’s because this post would be a quicky, but it took me far tooooo much time. Well, we want to use this stuff efficiently at our customers. So, “time well spend” (as a colleague would say) as now we can finally expose how it (the surrounding cache) exactly works…Also in the backend!
Let get right into it…
My journey started with chat from the administration team as they told me (or our team) that they see a lot of small BPMs being triggered in the PIM that all related to a dynamic enumerated property. We were a bid blown away as there was the expectation most of the time the “Cache” was used and not a new instance of a BPM. Guess what…Don’t assume things; Try them out! In our case we just didn’t match to full criteria list to make use of this cache…As always…It depends! 😏
My VM is already up and ready for hours, but now I finally got the time to dive into it (that’s what you get with customers…always keep them happy first!). We start with a basic project
entity (as always!); Not only a prj_name
property, but this time also a prj_state
property of type ‘Dynamic Enumerated Text’:
Select the Dynamic Enum property; Here we set the cache duration and here we add a new BPM:
We’ll create that
bpm_random
as next step! I did some preparation… 😉
The BPM editor opens now with a simple short-lived template that has an output message applied already for us; With name GetEnumerationOutputMessage
:
The only thing we need to do is adding a value to that output message; We can do this in the message map tab on the activity; Clean and simple like this:
1 | <!--FYI: This is a copy of the generated XML part for the output message--> |
Some notes on the mappings:
com.eibus.util.RandomString.getString()
is a public function; Read here how I found this knowledge- Make sure the function uses ‘Replace Content With Expression’ in its mapping
- We make the ‘Value’ to the ‘DisplayName’ to keep both the same
- ‘IsDefault’ will make this value selected directly in the dropdown; We only have one value to select from; Can be either
true|false
. - If you require more values in the final result dropdown; Read this post on for-loops.
…
Setting expectations; The power for this post is in the RandomString
function as we would like to see if the value changes on each refresh ONLY when the cache is expired (in our case after 30 sec.); In that case only one extra BPM instance will be seen in the PIM; Otherwise, the cache will jump in.
…
Time for a first double-check! After a full publication, move yourself into runtime, create a new project instance, open it and refresh your page a couple of times…Also, one time extra once the 30 sec. have passed. When looking at the PIM artifact, you should see only 2 instances passing by! Right? For me, it’s a green flag. ✅
In the end you will see something like this:
The selected value is my “old” value; The other value is a new value after the 30 sec.!
Testing time
Expectations are met, but I’m not satisfied as the administration team keeps complaining on constant BPM instance triggers!? Strange…What could cause this? Let’s try some scenarios to see if we can find a root cause for this (next to the already shown cache-refresh-interval setting on the Dynamic Enum property).
How about different users calling the form with a dropdown?
The above is done under my developer account awdev
; Using my second account awtest
does not change anything. The cache value is still received and when the interval is passing, I see a new instance passing by. So, that’s a cache over users within (I guess) the same organization. To get this busted, I did an hour of remote JVM debugging (over TomEE JPDA…Have a search. From the debugging results I can conclude that caching is done under the key combination of the ‘property’, the ‘locale’, and the ‘organization’! That sound logic to me! For the Java nerds 🤓 …I found this stuff in these classes:
1 | ///opt/tomee/latest/webapps/home#app#entityRestService/WEB-INF/lib/entityCore.jar |
What about a TomEE restart?
Interesting as I couldn’t get any trace (after my remote debug session) where this cache is physically saved. Well, I just did my restart of TomEE (systemctl restart tomee
) and guess what!? After a refresh of the form in runtime, I directly see a new BPM instance passing by in the PIM; That’s with a cache-refresh-interval setting of 30 min.! 😌 So, I conclude this cache is “in memory” of the JVM.
Let’s try adding a dependent property as input message!
Hmmmm…At this moment I still don’t have any trace why my Dynamic Enum property BPM would run on each refresh in the form UI!? Strange, the administrators keep complaining…Until I saw the light! 💡
A closer look at the form (of the customer) tells me the enumerated property is dependent on another property! AHA…!! So, we face a situation that looks more like this:
With a BPM update like this:
Right…Now let’s do a clean build, a publication, and a couple of refreshes of the form in runtime!
YES…there you have it! Our “problem”, or is it a “feature”? I guess it’s a feature; Sounds logic as well; or not!?. If the input changes and the output depends on it, you might get unexpected results! On the other hand, the above sample is already generating a random output, and you also don’t always know what result is of an external service call. By the way, if you don’t do anything with the input (as in my example) why all of a sudden the cache is skipped, and a new instance is triggered every time? Is it not up to the developer to decide what should happen in that case!? #SUPPORT…It’s an interesting discussion (which the product team probably also had during the implementation).
After a good night sleep; The input is off-course a dependent property of the current entity, so when the value of the dependent property changes you do want to trigger the BPM…Or not!? I think there are still use-cases possible to get a cache output based on a changed input…Comment me!
I was also thinking if it would be possible to skip the dependent input part (so, it uses the cache), do a ‘Read’ operation (via a webservice call) on the entity to grab our “input” value; That’s a nice thought, but will response different! In the above examples we refresh the page over and over to refresh our dynamic list, but in real life you want only the list to get a refresh on the input property change and that’s exactly what will NOT happen via this workaround.
It looks like we’re stuck with all the BPM instances in the PIM when the Dynamic Enum is dependent on a property! It is what it is. We could disable the full monitoring of the BPM, but that’s a different discussion I leave out of scope for this post. Enough of all the talking; I’m finishing off…
Lastly (I just can’t stop brainstorming about it)…IF, we could create an ‘onPropChange’ Rule on the input/dependent property that could fill a Dynamic Enum dropdown with values!? Would that help the world? Or is this the platform up-side-down? 🙃 Choices, choices!
That’s a great experienced “DONE”; Deep insights, a great overview on when the BPM-Enum-cache is used and (more important) when it’s NOT used. There is nothing more to explain; Consume the information for your project and ReThink again before you build your dynamic enumerated property. Have your best weekend with this new knowledge in mind, and I see you in another new post on AppWorks Tips.
Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?