[rules-users] Correlating 2 independent streams of events

Wolfgang Laun wolfgang.laun at gmail.com
Mon Jan 7 09:16:30 EST 2013


OK, so this is how I'd do it:

rule "shift EventA"
no-loop
when
    $triple: Last3A()
    $eva: EventA()
then
    modify( $triple ){
         setFirst( $triple.getSecond() ),
         setSecond(  $triple.getThird() ),
         setThird( $eva )
    }
end

rule "find in-between"
when
     $triple: Last3A($first: first, $third: third )
     $eva1: EventA( this == $first )
     $eva3: EventA( this == $third )
     $evb: EventB( this after $eva1 before $eva3 )
then
...
end

If you need all EventB's in a single Collection, use accumulate.

I haven't tried to locate the cause of the CCE, but I think it's due
to using an object of type Event from a field in Last3A in an
operation where there ought to be a timestamp. Probably some fall-back
reaction of the implementation of the temporal operator, might have to
read the Java code to be sure...

-W



On 07/01/2013, Esteban Aliverti <esteban.aliverti at gmail.com> wrote:
> Thanks Wolfgang.
> I was trying to solve the whole situation with just 1 rule, but not I'm
> trying to separate the problem in multiple rules. There are some
> bugs/language-limitations/programmer-skills-limitations that are preventing
> me to get the expected results though.
>
> Let's say I have a rule identifying my last 3 EventA (ALL my facts are
> declared as events):
>
>
> declare Last3A
>     @role(event)
>     firstEvent: EventA
>     lastEvent: EventA
> end
>
> rule 'Detect last 3'
> when
>    //some magic using sliding windows
> then
>    //$firstEventA and $lastEventA are the bounds identified in the LHS of
> the rule.
>    //EventA class doesn't have an explicit timestamp (drools is providing
> it) and I'd prefer to leave it that way.
>    insert (new Last3A($fistEventA, $lastEventA));
> end
>
>
> Then I have my rule trying to get the occurences of EventB that happen
> during a Last3A
>
> rule 'Get EventBs'
> when
>    $l: Last3A()
>    //originally, I've used a collect here since I wanted a single
> activation, but I'll use a single event here just to make syntax cleaner.
>    EventB(this after $l.firstEvent,this before $l.lastEvent)
> then
>    ...
> end
>
> If I try the latter rule, after I insert the third EventA (I'm calling
> fireAllRules() after each insertion) I get the following exception:
>
> *Exception executing consequence for rule "Detect last 3" in com.whatever:
> java.lang.ClassCastException: com.whatever.EventA cannot be cast to
> java.lang.Number*
> *...*
> *Caused by: java.lang.ClassCastException: **com.whatever.EventA** cannot be
> cast to java.lang.Number
> *
> *at
> org.drools.base.evaluators.AfterEvaluatorDefinition$AfterEvaluator.evaluateCachedLeft(AfterEvaluatorDefinition.java:341)
> *
>
> I'm assuming Drools is trying to cast the result of $l.firstEvent into a
> number (probably because it is expecting a timestamp) even though the
> result is already an Event.
>
> In order to avoid the $l.firstEvent and $l.lastEvent invocations I re-wrote
> the rule as follows (is ugly, I know):
>
> rule 'Get EventBs'
> when
>    $l: Last3A()
>    $firstEvent: EventA() from $l.getFirstEvent()
>    $lastEvent:  EventA() from $l.getLastEvent()
>    EventB(this after $firstEvent,this before $lastEvent)
> then
>    ...
> end
>
> The exception now is:
>
> *Exception executing consequence for rule **"Detect last 3"** in
> com.cognitive.nsf.management: java.lang.ClassCastException:
> org.drools.common.DefaultFactHandle cannot be cast to
> org.drools.common.EventFactHandle*
> *
> *
> What is happening now is that Drools doesn't realize that the object I'm
> using for after and before are actually Events.
> So it seems that temporal operators can only be used with events coming
> from the same rule (and not coming from a 'from' or any other black box).
> I'll continue digging on this, but it seems that the only solution will be
> to use explicit time stamps and then use them instead of the events in my
> marker fact.
>
> Best Regards,
>
>
>
>
>
>
> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
>
> Esteban Aliverti
> - Blog @ http://ilesteban.wordpress.com
>
>
> On Mon, Jan 7, 2013 at 12:17 PM, Wolfgang Laun
> <wolfgang.laun at gmail.com>wrote:
>
>> Use "wrapper" or "marker" facts to identify the last three EventA's
>> and a rule to "push" EventA's through these markers. Then, a simple
>> rule will give you all EventBs between the extremes of the marker set.
>>
>> Take care to get the start-up right ;-)
>>
>> -W
>>
>> On 07/01/2013, Esteban Aliverti <esteban.aliverti at gmail.com> wrote:
>> > Let's say I have two independent streams of different events: EventA
>> > and
>> > EventB. Which is the best way to get all the occurrences of EventB that
>> > happened between the last 3 occurrences of EventA?
>> >
>> > For example:
>> >
>> > from:
>> > $b1:EventB, $a1:EventA, $b2:EventB, $b3:EventB, $a2:EventA,
>> > $b4:EventB, $b5:EventB, $a3:EventA, $b6:EventB
>> >
>> > I would like to get $b2, $b3, $b4, $b5
>> >
>> > Best Regards,
>> >
>> >
>> >
>> >
>> > XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
>> >
>> > Esteban Aliverti
>> > - Blog @ http://ilesteban.wordpress.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