[rules-users] CEP accumulate unclear behavior

Wolfgang Laun wolfgang.laun at gmail.com
Wed Dec 4 10:58:15 EST 2013


Hi ters,

I've run a few tests and I think that you'll have to use an entirely
different approach to achieve what you want.

accumulate creates a "virtual object" maintaining the accumulated
value(s). This is updated with every change to its domain, i.e., the
set of matching facts. Thus, for every inserted "MyService" the rule
will fire. (If you add some other pattern, then all matching products
result in an activation. So my advice for seeing the average for every
insert was wrong.)

You could write your own accumulate function (using the
init/action/result paradigm) where you accumulate over all
ServicePerformanceEvent events but count and sum only the "MyService"
events.

Alternatively, use a fact of a class that contains a count and a sum
and use this to collect the average:


public class Accu {
    private String trigger;
    private int sum;
    private int count;
    public Accu( String t ){
        trigger = t;
    }
    public String getTrigger(){ return trigger; }
    public int getAverage(){ return sum/count; }
    public void accumulate( int value ){
	sum += value;
	count++;
    }
}

rule a when
     $event : Event( $source: source, $value: value)
     $accu: Accu( trigger == $source )
then
     $accu.accumulate( $value );
     System.out.println("$events avg value = " + $accu.getAverage() );
end

rule b when
     $event : Event( $source: source, $value: value)
     $accu: Accu( trigger != $source )
then
     System.out.println("$events avg value = " + $accu.getAverage() );
end

Cheers
-W

On 04/12/2013, ters <ters at ukr.net> wrote:
> laune, thanks for fast reply! So from point to point:
>
> *-- "Are you using 5.4.0?"*
> Yes, I'm using 5.4.0.Final.
>
> *-- "But you can easily achieve what you want by adding the pattern
> ServicePerformanceEvent() in front of the accumulate CE."*
> I've tested this, LHS is:
> /        ServicePerformanceEvent()
> accumulate(ServicePerformanceEvent(serviceName == "MyService",
> $thisDuration
> : duration);
>     		       $avg : average($thisDuration));/
>
> The result is:
> -= 1 =-
> $events avg duration = 2.0
> ----------FIRED----------
> -= 2 =-
> $events avg duration = 2.0
> ----------FIRED----------
> -= 3 =-
> $events avg duration = 7.0
> ----------FIRED----------
> $events avg duration = 7.0
> ----------FIRED----------
> $events avg duration = 7.0
> ----------FIRED----------
> ---test end---
>
> Now (e.g. in case -3-) rule fires on all already inserted/processed events!
> but I expect (in case -3-) firing only for last inserting event which is
> not
> processed before, that is:
> -= 1 =-
> $events avg duration = 2.0
> ----------FIRED----------
> -= 2 =-
> $events avg duration = 2.0
> ----------FIRED----------
> /-= 3 =-
> $events avg duration = 7.0
> ----------FIRED----------/
> ---test end---
>
> *--"Can you try with a later version?"*
> I've just tried with 6.0.0.Final version. Now result of Third rule becomes
> the same for both fireAllRules and fireUntilHalt tests (good point):
> /////Third rule:
> 	when
> 		$event : ServicePerformanceEvent(serviceName == "MyService");
>         accumulate(ServicePerformanceEvent(serviceName == "MyService",
> $thisDuration : duration);  $avg : average($thisDuration));
> 	then
>         System.out.println("$event.duration = " + $event.duration);
>         System.out.println("$events avg duration = " + $avg);
>         System.out.println("----------FIRED----------");
> end		/
>
> Result:
> -= 1 =-
> $event.duration = 2
> $events avg duration = 2.0
> ----------FIRED----------
> -= 2 =-
> -= 3 =-
> $event.duration = 2
> $events avg duration = 7.0
> ----------FIRED----------
> $event.duration = 12
> $events avg duration = 7.0
> ----------FIRED----------
> ---test end---
>
> As can see, in case -3-, rule fires 2 times - on already inserted and
> processed as fact event with duration=2 and
> on the event with duration=12 which inserted just now and was not processed
> as fact before.
>
> Actually what I want in this case - the rule should fire only on events
> restricted with serviceName constraint, /*which are not
> processed as fact/not-fact before (inserted between fireAllRules()
> calls)*/,
> but average should be calculated for all existed in wm events considering
> serviceName constraint.
> I.e. my expectation for Third rule result is:
> / -= 1 =-
> $event.duration = 2
> $events avg duration = 2.0
> ----------FIRED----------
> -= 2 =-
> *-= 3 =-
> $event.duration = 12
> $events avg duration = 7.0*
> ----------FIRED----------
> ---test end---/
>
> How I can achieve this behavior???
>
>
>
>
> --
> View this message in context:
> http://drools.46999.n3.nabble.com/CEP-accumulate-unclear-behavior-tp4027069p4027088.html
> Sent from the Drools: User forum mailing list archive at Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>


More information about the rules-users mailing list