[rules-users] Rule looping question

Enda J Diggins ejdiggins at gmail.com
Wed Mar 10 07:54:56 EST 2010


Hi Glenn,

I'm going to start with the looping issue. The quick answer is use
lock-on-active instead of no-loop.
This is the important bit of code as far as I'm concerned:

            $tholdBreach : Parameter.Threshold(windowSize == 15,

                  threshold >= $averageUpdateValue) *from* $param.thresholds

            $firedAlert : AlertInformation(name == $param.name,

                  severity != $tholdBreach.severity)
So, the first time you run through this code you have data like the
following:

Thresholds [ Threshold1{severity = MINOR, ...}, Threshold2{severity =
CRITICAL, ...} ]

AlertInformation{severity = null, ...}

Execution 1)
 Iteration 1 - AlertInformation.severity != Threshold1.severity
  Result: Set AlertInformation.severity to MINOR

Execution 2)
Iteration 1 - AlertInformation.severity == Threshold1.severity // do nothing
Iteration 2 - AlertInformation.severity != Threshold2.severity
  Result: Set AlertInformation.severity to CRITICAL

This pattern repeats giving you your infinite loop. Does that make sense?
You have a list of items you are using for your comparison. The rule will
only stop firing when the severity value in AlertInformation matches the
severity values on every item in the list. Which can never happen.
Lock-on-active will stop the rule from being reactivated as a result of its
own execution. This should help but is probably not the best solution. You
should look at tightening up your rules some more.

Your other issue, if I understand you correctly, is that you are having
trouble with the order the of the list and don't want to have to sort it
before adjudication, right?

If so, maybe you could use the 'not' keyword as follows:

            $tholdBreach : Parameter.Threshold(windowSize == 15,

                  threshold >= $averageUpdateValue) *from* $param.thresholds

            $firedAlert : AlertInformation(name == $param.name,

                  severity != $tholdBreach.severity)
                         not Parameter.Threshold(windowSize == 15, threshold
< $tholdBReach, threshold >= $averageUpdateValue) from
                                 $param.thresholds

Here, I am checking to ensure there is not another Threshold with a lower
threshold than the one in $tholdBreach that still satisfies our other
criteria.

There's probably an easier way, but hopefully that will give you some ideas!

Hope it helps,
Enda

2010/3/10 Glenn Macgregor <gmacgregor at pocketkings.ie>

>  Hi All,
>
>
>
> I am in the process of creating some rules for a POC I am doing using
> drools, having some issues understanding why I have an infinite loop in a
> rule.
>
>
>
> Rule in question:
>
>
>
> *rule* "Check Parameter Threshold Update Breach"
>
>       *no-loop* *true*
>
>       *when*
>
>             ParameterUpdateEvent($name : name)
>
>                   *from* entry-point "ParamUpdateStream"
>
>             $param : Parameter(name == $name)
>
>             Number($averageUpdateValue : doubleValue)
>
>                   *from* *accumulate*(ParameterUpdateEvent(name == $
> param.name, $value : value)
>
>                   over window:time(15m)
>
>                   *from* entry-point "ParamUpdateStream", average($value))
>
>             $tholdBreach : Parameter.Threshold(windowSize == 15,
>
>                   threshold >= $averageUpdateValue) *from*$param.thresholds
>
>             $firedAlert : AlertInformation(name == $param.name,
>
>                   severity != $tholdBreach.severity)
>
>       *then*
>
>             System.out.println("Updating alert from '" +
> $firedAlert.getSeverity() +
>
>                   "' to '" + $tholdBreach.getSeverity() +
>
>                   "' alarm: Average update value for " +
>
>                   $param.getName() + " = " + $averageUpdateValue);
>
>             $firedAlert.setSeverity($tholdBreach.getSeverity());
>
>             *update*($firedAlert);
>
>             //insert(new AlertInformation($param.getName(),
> $tholdBreach.getSeverity()));
>
>             //modify($firedAlert);
>
> *end*
>
> * *
>
> I understand what is happening up to the $tholdBreach : Parameter.Threshold
> line. Each Parameter can have a list of thresholds and what I want this line
> to do is pick the correct threshold if any are breached. For instance Param1
> has 2 thresholds: MINOR and CRITICAL, the MINOR threshold should fire if
> averageUpdateValue is >= 50, the CRITICAL threshold should fire if
> averageUpdateValue is >= 40. The first problem I need to solve (in a better
> way) is getting the correct threshold out of this, the way I do it now is
> but putting the MINOR threshold in the list before the CRITICAL one. This
> means that it will be checked first from the line in question. This, to me,
> is not a good solution. Is there a more deterministic way to do this, I was
> thinking of somehow using the difference between the threshold and the
> averageUpdateValue to get the right now but I don’t see how that can work
> from a rule stand point.
>
>
>
> The other question I have is this rule loops infinitely when the
> averageUpdateValue is below 40 (CRITICAL threshold)  between a MINOR alarm
> and a CRITICAL alarm and I don’t see why or how because tholdBreach  should
> always be the CRITICAL alarm and the rule would stop on the next line, but
> it is alernatly  returning CRITICAL then MINOR which is confusing. To
> confuse this even more when I comment out the update($firedAlert) and
> replace that with a retract($firedAlert) and insert(new …) it does not loop.
>
>
>
> Any ideas would be great.
>
>
>
> Thanks
>
>
>
>  Glenn
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>


-- 
Enda J Diggins
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20100310/c2453e74/attachment.html 


More information about the rules-users mailing list