As to the second test, what you observe is correct. All hell would
break loose in most KBs if rules *not* referring to a certain fact would
fire when such a fact is inserted! But you can easily achieve what
you want by adding the pattern
ServicePerformanceEvent()
in front of the accumulate CE.
The result of the third rule and test looks like a bug to me. There's
no version 5.0.4. Are you using 5.4.0? Can you try with a later
version?
-W
On 03/12/2013, ters <ters(a)ukr.net> wrote:
Hi all. Respected experts of drools, please help me to understand
how
pattern
+ accumulate behave.
I believe that an example is the best way to explain the problem, maybe it
will look bulky, but suppose be enough.
I use CEP and EventProcessingOption.Stream.
Event class:
/public class ServicePerformanceEvent {
private String serviceName;
private Integer duration;
public ServicePerformanceEvent(String name, Integer duration) {
serviceName = name;
this.duration = duration;
}
}/
There are 2 tests, 1st - with fireAllRules invocation, 2nd - with
firwUntilHalt invocation.
/ @Test
public void *test1_FireAllRules() *throws RuleGeneratorException {
System.out.println("-= 1 =-");
ksession.insert(new ServicePerformanceEvent("MyService", 2));
ksession.fireAllRules();
System.out.println("-= 2 =-");
ksession.insert(new ServicePerformanceEvent("AnotherService", 10));
ksession.fireAllRules();
System.out.println("-= 3 =-");
ksession.insert(new ServicePerformanceEvent("MyService", 12));
ksession.fireAllRules();
System.out.println("---test1 end---");
}
@Test
public void *test2_FireUntilHalt()* throws RuleGeneratorException,
InterruptedException {
System.out.println("-= 1 =-");
ksession.insert(new ServicePerformanceEvent("MyService", 2));
runFireUntilHaltThread();
Thread.sleep(1000);
System.out.println("-= 2 =-");
ksession.insert(new ServicePerformanceEvent("AnotherService", 10));
Thread.sleep(1000);
System.out.println("-= 3 =-");
ksession.insert(new ServicePerformanceEvent("MyService", 12));
Thread.sleep(1000);
System.out.println("---test2 end---");
}/
There are 3 simple rules for which I performing tests:
*////First Rule:*
declare com.test.event.ServicePerformanceEvent
@role( event )
end
rule "ServicePerformanceEvent test rule1"
dialect "mvel"
when
$event : ServicePerformanceEvent(serviceName == "MyService");
then
System.out.println("$event.duration = " + $event.duration);
System.out.println("----------FIRED----------");
end
Invocation results of the test1_FireAllRules() and test2_FireUntilHalt()
the
same:
-= 1 =-
$event.duration = 2
----------FIRED----------
-= 2 =-
-= 3 =-
$event.duration = 12
----------FIRED----------
---test end---
Actual: As expected rule fires for each new inserted event with desired
serviceName "MyService" (- behavior is clear).
*////Second rule:*
rule "ServicePerformanceEvent test rule2"
dialect "mvel"
when
accumulate(ServicePerformanceEvent(serviceName == "MyService",
$thisDuration : duration); $avg : average($thisDuration));
then
System.out.println("$events avg duration = " + $avg);
System.out.println("----------FIRED----------");
end
Invocation results of the test1_FireAllRules() and the
test2_FireUntilHalt()
the same again:
-= 1 =-
$events avg duration = 2.0
----------FIRED----------
-= 2 =-
-= 3 =-
$events avg duration = 7.0
----------FIRED----------
---test end---
Actual: Now rule accumulates average only for events from working memory
with desired serviceName (-this is clear) but fires only for inserted
events
with expected serviceName "MyService" (- not clear)
*My expectation*: rule must fire for each currently inserted event and
average must be calculated for all events from working memory with
serviceName=="MyService".
*////Third rule:*
/rule "ServicePerformanceEvent test rule3"
dialect "mvel"
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/
Invocation results of the test1_FireAllRules():
-= 1 =-
$events avg duration = 2.0
----------FIRED----------
-= 2 =-
-= 3 =-
$events avg duration = 7.0
----------FIRED----------
$events avg duration = 7.0
----------FIRED----------
---test1 end---
Actual: In case -=3=- rule fires for each event into working memory during
average calculation (- not clear)
*My expectation*: firing rule only for current/last inserted event and
calculation average for all events into working memory considering
sevriceName=="MyService".
Invocation results of the test2_FireUntilHalt():
-= 1 =-
$events avg duration = 2.0
----------FIRED----------
-= 2 =-
-= 3 =-
$events avg duration = 2.0
----------FIRED----------
$events avg duration = 7.0
----------FIRED----------
$events avg duration = 7.0
----------FIRED----------
---test2 end---
OR (with another sleep time)
-= 1 =-
$events avg duration = 2.0
----------FIRED----------
-= 2 =-
-= 3 =-
$events avg duration = 7.0
----------FIRED----------
$events avg duration = 7.0
----------FIRED----------
$events avg duration = 7.0
----------FIRED----------
---test2 end---
This results I can't explain and understand.
Could anyone help me to understand this pattern + accumulate behavior.
I spent a lot of time on my actual project task but with no result .
*The actual task is*:
Rule must fire for last inserted event if its serviceName equals to
"MyService" and
its duration greater than average duration of all events with same
serviceName from the working memory.
On the project we use fireUntilHalt strategy.
I really hope and appreciate any help. Thanks in advance.
--
View this message in context:
http://drools.46999.n3.nabble.com/CEP-accumulate-unclear-behavior-tp40270...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users