How to avoid re-propagating entire object?
by Tom.E.Murphy@wellsfargo.com
Apologies if this question has been addressed before.
We generate our Drools rules automatically from a business rules repository we've had here for years.
Currently, our code generator is doing something I'd rather not have to do - it inspects assignments on the RHS and inserts "anti-recursion" logic into the LHS.
This leads to rules like the following:
rule "RS6631.1.2"
no-loop true
dialect "mvel"
when
$policySet : PolicySet
(
marketType == MarketTypeEnum.FHA
# anti-recursion logic derived from assignments in action section
, isSetSelectedDecisionIndicator == false
|| selectedDecisionIndicator != true
# end anti-recursion logic
)
then
modify($policySet)
{
selectedDecisionIndicator = true
};
end
Notice the two lines between the comments - the code generator has analyzed the assignment on the RHS and has inserted this defensive logic in order to prevent (possibly infinite) re-firings of this rule anytime other rules also update the PolicySet object. This approach does not work in all scenarios, however, and there is an occasional struggle by our rule analysts to find ways to suppress the loops caused by rule "A" updating an object versus rule "B" updating the same object, even when the attributes changed by the two rules are different.
The root issue, I believe, is that the modify and update require fact handles that refer to whole objects, not to individual attributes of those objects. When an attribute value is updated, my intuition suggests that only the new value of that attribute should be propagated through the network, not the whole object. Re-propagating the entire object causes all rules that have already fired to be reactivated, since their conditions are still true. All we really want is that the rules whose conditions NEWLY match both the unchanged attributes and the changed attributes should be activated, not rules that matched previously on the unchanged attributes and whose CE's or constraints have not been affected by the change.
I've seen several conversations on this list about how to prevent infinite loops. "No-loop" only seems to work within the context of the current rule. Two rules that update an object, even if their changes are to non-overlapping attributes, cause each other to be reactivated in the absence of some defensive logic like that shown above. "Lock-on-active" doesn't appear to achieve the goal either, because it suppresses firings that might in fact be desired.
Feel free to educate me if my limited understanding is showing here.
But does anyone know of a way to tell the Drools engine to only propagate the attributes that have changed, and not the entire object?
Tom Murphy
Wells Fargo HCFG - CORE Deal Decisioning Platform