Hello,
I would like to improve the performance of my Drools
process, I have two questions on my current implementation, one regarding
updating fact and the other retracting them.
My company is a bank where traders are making deals
on markets, these deals must be classified in book, this is what we call “booking
process”.
Booking is done according to booking criteria :
which trader has made the deal ? on which product ? etc …
A booking rule defines a set of criteria and the target
book where the deal will classified.
I’m using Drools to :
I have defined a flow composed of 3 steps/rules
group, each group has one rule, here’s the flow and the rules.
Flow :
------
"Find matching booking rules by deal group" -> "Refresh"
-> "Apply booking rule group"
Rules :
------
The job of this rule is to store in DealMatchingBookingRules all
the booking rule matching a specific deal (each DealMatchingBookingRules instance
has a unique Deal).
rule "Find
matching booking rules by deal"
salience 10
no-loop
ruleflow-group "Find
matching booking rules by deal group"
when
$dealMatchingBookingRules :
DealMatchingBookingRules($dealModel : deal)
$dealProductRelatedIndexes :
ProductRelatedIndexes(product.internalCode == $dealModel.product.internalCode)
$bookingRule : BTExecutionBookingRuleModel (
//
when a criterion is not set, it is considered as satisfied.
(traderCriterion == null || $dealModel.trader ==
traderCriterion)
&& (portfolioCriterion == null || $dealModel.portfolio ==
portfolioCriterion)
//
when a product type criterion is set to unknown, it is considered as satisfied
whatever deal product type is.
&& (productTypeStringCriterion == null || productTypeCriterion ==
ProductType.Unknown
|| $dealModel.product.productType ==
productTypeCriterion)
&& (listedIndexCriterion == null ||
$dealProductRelatedIndexes.relatedIndexes contains listedIndexCriterion)
)
then
$dealMatchingBookingRules.addMatchingBookingRule($bookingRule);
end
This second step is
only here to tell Drools that DealMatchingBookingRules have changed, this is needed
for the next step.
I can’t call “update($dealMatchingBookingRules)”
in the previous rule, because if 2 booking rule matches the same deal, an
infinite loop occurs.
My explanation is the
following one (as far as I understand how Drools works) :
1 – Drools rule
is activated for first booking rule => $dealMatchingBookingRules is updated
2 - Drools rule is
activated for second booking rule => $dealMatchingBookingRules is updated
3 - since
$dealMatchingBookingRules has been updated for Drools it will execute again the
rule for first booking rule
4 - since
$dealMatchingBookingRules has been updated for Drools it will execute again the
rule for second booking rule
It continues to execute
step 3, then step 4, then step 3 ... infinite loop !
Question :
Is there a better way
of telling Drools that DealMatchingBookingRules have changed and avoid activating
the rule again ?
If none, can I update all
DealMatchingBookingRules
more efficiently ?
rule "Refresh"
salience 5
no-loop
ruleflow-group "Refresh"
when
$dealMatchingBookingRules : DealMatchingBookingRules()
then
update($dealMatchingBookingRules);
end
Last rule job (and last
flow step), is to determine which booking rule to apply among the ones matching
a specific deal.
When we find the right booking
rule, we book the deal and process is finished for the deal.
Questions :
I think that no-loop
and the retract isntruction are doing the same job, question is which the one
to remove to have the best performance improvement and why ?
(I will launch performance
test anyway but It would be cool to have some insight on Drools)
rule "Apply
booking rule"
no-loop
ruleflow-group "Apply
booking rule group"
when
$dealMatchingBookingRules : DealMatchingBookingRules(
hasSingleMatchingLevel1BookingRule == true
||
hasSingleMatchingLevel2BookingRule == true
||
hasSingleMatchingLevel3BookingRule == true
||
hasSingleMatchingLevel4BookingRule == true
)
then
MarketDealModel dealModel =
$dealMatchingBookingRules.getDeal();
if ($dealMatchingBookingRules.getHasSingleMatchingLevel1BookingRule())
{
BTExecutionBookingRuleModel effectiveBookingRuleModel =
$dealMatchingBookingRules.getSingleMatchingLevel1BookingRule();
effectiveBookingRuleModel.applyRuleOnDeal(dealModel);
} else if
($dealMatchingBookingRules.getHasSingleMatchingLevel2BookingRule()) {
BTExecutionBookingRuleModel effectiveBookingRuleModel =
$dealMatchingBookingRules.getSingleMatchingLevel2BookingRule();
effectiveBookingRuleModel.applyRuleOnDeal(dealModel);
} else if
($dealMatchingBookingRules.getHasSingleMatchingLevel3BookingRule()) {
BTExecutionBookingRuleModel effectiveBookingRuleModel =
$dealMatchingBookingRules.getSingleMatchingLevel3BookingRule();
effectiveBookingRuleModel.applyRuleOnDeal(dealModel);
} else if
($dealMatchingBookingRules.getHasSingleMatchingLevel4BookingRule()) {
BTExecutionBookingRuleModel effectiveBookingRuleModel
= $dealMatchingBookingRules.getSingleMatchingLevel4BookingRule();
effectiveBookingRuleModel.applyRuleOnDeal(dealModel);
}
retract($dealMatchingBookingRules);
end
So to summarize my questions :
1.
In my specific case, is
there a way to update facts without activating same rules again ?
2.
What is the more efficient
between no-loop or retract ?
Thanks in advance for your lights,
Regards,
Joël Costigliola