[rules-users] Accumulator being executed depending on the number of events

Wolfgang Laun wolfgang.laun at gmail.com
Fri Jun 22 13:21:40 EDT 2012


(Something strange is indeed going on which does result in differences
between accumulate functions with and without reverse. But I see now
that this is not what worries you. Sorry - but read on.)

This particular condition:
  when
     $event: TestEvent( $key:key)	
     $total : Number( )  from accumulate( event : TestEvent( key ==
$key  ) , test( 1 ) )
  then

results in a first evaluation for the first TestEvent(), creating one
activation, binding $event to this TestEvent(). When the second
TestEent() is inserted, another activation is added, this time with
$event bound to the second TestEvent(), and another accumulate is
required. The first accumulate is extended to include the second
TestEvent; the second accumulate computes, from scratch, for both. The
same thing happens with the third TestEvent so that you now have three
separate accumulates.

If you want to compute once and only once for each value of
TestEvent.key, you'll have to avoid the spurious activations for
successive TestEvents with the same key, e.g.,
  when
     $event: TestEvent( $key:key )
     not TestEvent( key == $key, this after $event )
     $total : Number( )  from accumulate( event : TestEvent( key ==
$key  ) , test( 1 ) )
  then

-W









On 22/06/2012, ekzl at yahoo.com <ekzl at yahoo.com> wrote:
> Hi Wolfgang,
>
> I couldn't agree more with your analysis unfortunately it seems that or i
> have something wrong with my rule or there is something wrong with the
> implementation?
>
> First off all the reserve was set to false this would mean that once the
> rule is finished the context shouldn't be available any more and therefore
> not updated when the rule is executed again  (as recalculation would
> require
> all the facts to be processed again anyway). Now if my understanding is
> correct then this is not how drools behaves, you can see evidence of this
> in
> the trace of the first post.
>
> I tried returning true for the reverse but the behaviour is exactly the
> same. Each new fact creates a new context then for all matching facts the
> accuulate is called on that context. The accumulate method is called on all
> existing contexts for the new fact.
>
> Here is the rule (test just makes a sum of the values)
>
> import eu.mc2bis.drools.TestEvent;
>
> declare TestEvent
> 	@role(event)
> 	@timestamp( eventDate )
> end
>
> rule "test accumulator"
>   salience 100 // Make sure this rule is always executed by giving it a
> very
> high salience
>   no-loop true
> when
> 	$event: TestEvent( $key:key)	
>     $total : Number( )  from accumulate( event : TestEvent( key == $key  ) ,
>
> test( 1 ) )									
> then
> 	System.out.println("-- Rule output Total for key:" + $key + " total:"  +
> $total);
> end
>
>
> here is the output with reverse:false
>
> Main:inserting event with key:0
> -> Accumulator: Context created:553
> -> Accumulator: Init called for context:553
> -> Accumulator: getResults() called for context:553
> -> Accumulator: accumulate called for context:553 key:553 value:1
> -> Accumulator: getResults() called for context:553
> Main:fireAllRules start
> -- Rule output Total for key:0 total:1
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Context created:454
> -> Accumulator: Init called for context:454
> -> Accumulator: accumulate called for context:454 key:454 value:1
> -> Accumulator: getResults() called for context:454
> -> Accumulator: accumulate called for context:553 key:553 value:1
> -> Accumulator: accumulate called for context:454 key:454 value:1
> -> Accumulator: getResults() called for context:454
> -> Accumulator: getResults() called for context:553
> Main:fireAllRules start
> -- Rule output Total for key:0 total:2
> -- Rule output Total for key:0 total:2
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Context created:695
> -> Accumulator: Init called for context:695
> -> Accumulator: accumulate called for context:695 key:695 value:1
> -> Accumulator: accumulate called for context:695 key:695 value:1
> -> Accumulator: getResults() called for context:695
> -> Accumulator: accumulate called for context:553 key:553 value:1
> -> Accumulator: accumulate called for context:454 key:454 value:1
> -> Accumulator: accumulate called for context:695 key:695 value:1
> -> Accumulator: getResults() called for context:695
> -> Accumulator: getResults() called for context:454
> -> Accumulator: getResults() called for context:553
> Main:fireAllRules start
> -- Rule output Total for key:0 total:3
> -- Rule output Total for key:0 total:3
> -- Rule output Total for key:0 total:3
> Main:fireAllRules finished
> Time (ms) required to update: 100k profiles = 30
> Ended
>
> I would have expected:
>
> Main:inserting event with key:0
> -> Accumulator: Context created:553
> -> Accumulator: Init called for context:553
> -> Accumulator: getResults() called for context:553
> -> Accumulator: accumulate called for context:553 key:553 value:1
> -> Accumulator: getResults() called for context:553
> Main:fireAllRules start
> -- Rule output Total for key:0 total:1
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Context created:454
> -> Accumulator: Init called for context:454
> -> Accumulator: accumulate called for context:454 key:454 value:1
> -> Accumulator: getResults() called for context:454
> -> Accumulator: accumulate called for context:454 key:454 value:1
> -> Accumulator: getResults() called for context:454
> Main:fireAllRules start
> -- Rule output Total for key:0 total:2
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Context created:695
> -> Accumulator: Init called for context:695
> -> Accumulator: accumulate called for context:695 key:695 value:1
> -> Accumulator: accumulate called for context:695 key:695 value:1
> -> Accumulator: getResults() called for context:695
> -> Accumulator: accumulate called for context:695 key:695 value:1
> -> Accumulator: getResults() called for context:695
> Main:fireAllRules start
> -- Rule output Total for key:0 total:3
> Main:fireAllRules finished
> Time (ms) required to update: 100k profiles = 30
> Ended
>
>
> Here is the output with reverse:true
>
> Main:inserting event with key:0
> -> Accumulator: Context created:943
> -> Accumulator: Init called for context:943
> -> Accumulator: getResults() called for context:943
> -> Accumulator: accumulate called for context:943 key:943 value:1
> -> Accumulator: getResults() called for context:943
> Main:fireAllRules start
> -- Rule output Total for key:0 total:1
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Context created:677
> -> Accumulator: Init called for context:677
> -> Accumulator: accumulate called for context:677 key:677 value:1
> -> Accumulator: getResults() called for context:677
> -> Accumulator: accumulate called for context:943 key:943 value:1
> -> Accumulator: accumulate called for context:677 key:677 value:1
> -> Accumulator: getResults() called for context:677
> -> Accumulator: getResults() called for context:943
> Main:fireAllRules start
> -- Rule output Total for key:0 total:2
> -- Rule output Total for key:0 total:2
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Context created:968
> -> Accumulator: Init called for context:968
> -> Accumulator: accumulate called for context:968 key:968 value:1
> -> Accumulator: accumulate called for context:968 key:968 value:1
> -> Accumulator: getResults() called for context:968
> -> Accumulator: accumulate called for context:943 key:943 value:1
> -> Accumulator: accumulate called for context:677 key:677 value:1
> -> Accumulator: accumulate called for context:968 key:968 value:1
> -> Accumulator: getResults() called for context:968
> -> Accumulator: getResults() called for context:677
> -> Accumulator: getResults() called for context:943
> Main:fireAllRules start
> -- Rule output Total for key:0 total:3
> -- Rule output Total for key:0 total:3
> -- Rule output Total for key:0 total:3
> Main:fireAllRules finished
> Time (ms) required to update: 100k profiles = 32
> Ended
>
>
> I would have expected:
>
> Main:inserting event with key:0
> -> Accumulator: Context created:943
> -> Accumulator: Init called for context:943
> -> Accumulator: getResults() called for context:943
> -> Accumulator: accumulate called for context:943 key:943 value:1
> -> Accumulator: getResults() called for context:943
> Main:fireAllRules start
> -- Rule output Total for key:0 total:1
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Init called for context:943
> -> Accumulator: accumulate called for context:943 key:943 value:1
> -> Accumulator: getResults() called for context:943
> Main:fireAllRules start
> -- Rule output Total for key:0 total:2
> Main:fireAllRules finished
> Main:inserting event with key:0
> -> Accumulator: Init called for context:943
> -> Accumulator: accumulate called for context:943 key:943 value:1
> -> Accumulator: getResults() called for context:943
> Main:fireAllRules start
> -- Rule output Total for key:0 total:3
> Main:fireAllRules finished
> Time (ms) required to update: 100k profiles = 32
> Ended
>
>
> Thank you for being so patient with me I'm sure I must be doing something
> wrong?
> Can you point me out to some documentation or sequence diagram how this is
> designed (if possible) or perhaps i just need to read the code ;-)
>
> Best Regards,
> e
>
> --
> View this message in context:
> http://drools.46999.n3.nabble.com/Accumulator-being-executed-depending-on-the-number-of-events-tp4018128p4018158.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