Drools: get the 3 most recent Events

前端 未结 2 1856
自闭症患者
自闭症患者 2020-12-20 23:10

I\'m working on a small Drools project, because I want to learn more about using rule engines. I have a class called Event that has the following fields:

<
2条回答
  •  一整个雨季
    2020-12-20 23:51

    I was able to simplify 'not logic' like this

    rule "Three most recent events tagged with 'OK'"
    when
        $e1 : Event( tag == "OK")
        $e2 : Event( tag == "OK", millis < $e1.millis )
        $e3 : Event( tag == "OK", millis < $e2.millis )
        not Event( this != $e2, tag == "OK", $e3.millis < millis, millis < $e1.millis )
    then
        System.out.printf("%s - %s - %s%n", $e1, $e2, $e3);
    end
    

    There was nothing said about cleaning events. Usually this is desirable, so you can achieve the same logic with deletion of the last event:

    rule "Three most recent events tagged with 'OK'"
    when
        $e1 : Event( tag == "OK")
        $e2 : Event( tag == "OK", millis < $e1.millis )
        $e3 : Event( tag == "OK", millis < $e2.millis )
    then
        System.out.printf("%s - %s - %s%n", $e1, $e2, $e3);
        retract ($e3)
    end
    

    Let say each second you'll insert an event one 'OK' another empty '', here is the test:

    @DroolsSession("classpath:/test3.drl")
    public class PlaygroundTest {
        
        @Rule
        public DroolsAssert drools = new DroolsAssert();
        
        @Test
        public void testIt() {
            for (int i = 0; i < 10; i++) {
                drools.advanceTime(1, SECONDS);
                drools.insertAndFire(new Event(i % 2 == 0 ? "OK" : "", i));
            }
        }
    }
    

    all three variants will produce the same triggering logic:

    00:00:01 --> inserted: Event[tag=OK,millis=0]
    00:00:01 --> fireAllRules
    00:00:02 --> inserted: Event[tag=,millis=1]
    00:00:02 --> fireAllRules
    00:00:03 --> inserted: Event[tag=OK,millis=2]
    00:00:03 --> fireAllRules
    00:00:04 --> inserted: Event[tag=,millis=3]
    00:00:04 --> fireAllRules
    00:00:05 --> inserted: Event[tag=OK,millis=4]
    00:00:05 --> fireAllRules
    00:00:05 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [Event, Event, Event]
    OK4 - OK2 - OK0
    00:00:06 --> inserted: Event[tag=,millis=5]
    00:00:06 --> fireAllRules
    00:00:07 --> inserted: Event[tag=OK,millis=6]
    00:00:07 --> fireAllRules
    00:00:07 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [Event, Event, Event]
    OK6 - OK4 - OK2
    00:00:08 --> inserted: Event[tag=,millis=7]
    00:00:08 --> fireAllRules
    00:00:09 --> inserted: Event[tag=OK,millis=8]
    00:00:09 --> fireAllRules
    00:00:09 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [Event, Event, Event]
    OK8 - OK6 - OK4
    00:00:10 --> inserted: Event[tag=,millis=9]
    00:00:10 --> fireAllRules
    

    variant with window:length(3) will also deal with last 3 OK events. It is different on the beginning though: it will be triggered for 1 and 2 first OK events too. It will be also triggered once with empty list on the beginning if session doesn't contain any events. According to documentation, sliding windows start to match immediately and defining a sliding window does not imply that the rule has to wait for the sliding window to be "full" in order to match. For instance, a rule that calculates the average of an event property on a window:length(10) will start calculating the average immediately, and it will start at 0 (zero) for no-events, and will update the average as events arrive one by one.

    00:00:01 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [InitialFactImpl, UnmodifiableRandomAccessList]
    []
    00:00:01 --> inserted: Event[tag=OK,millis=0]
    00:00:01 --> fireAllRules
    00:00:01 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [InitialFactImpl, UnmodifiableRandomAccessList]
    [OK0]
    00:00:02 --> inserted: Event[tag=,millis=1]
    00:00:02 --> fireAllRules
    00:00:03 --> inserted: Event[tag=OK,millis=2]
    00:00:03 --> fireAllRules
    00:00:03 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [InitialFactImpl, UnmodifiableRandomAccessList]
    [OK0, OK2]
    00:00:04 --> inserted: Event[tag=,millis=3]
    00:00:04 --> fireAllRules
    00:00:05 --> inserted: Event[tag=OK,millis=4]
    00:00:05 --> fireAllRules
    00:00:05 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [InitialFactImpl, UnmodifiableRandomAccessList]
    [OK0, OK2, OK4]
    00:00:06 --> inserted: Event[tag=,millis=5]
    00:00:06 --> fireAllRules
    00:00:07 --> inserted: Event[tag=OK,millis=6]
    00:00:07 --> fireAllRules
    00:00:07 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [InitialFactImpl, UnmodifiableRandomAccessList]
    [OK2, OK4, OK6]
    00:00:08 --> inserted: Event[tag=,millis=7]
    00:00:08 --> fireAllRules
    00:00:09 --> inserted: Event[tag=OK,millis=8]
    00:00:09 --> fireAllRules
    00:00:09 <-- 'Three most recent events tagged with 'OK'' has been activated by the tuple [InitialFactImpl, UnmodifiableRandomAccessList]
    [OK4, OK6, OK8]
    00:00:10 --> inserted: Event[tag=,millis=9]
    00:00:10 --> fireAllRules
    

提交回复
热议问题