Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-256

Sliding Window rule duplicate fireing after fireAllRules() loop

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 5.5.1.Final
    • 5.5.0.Final
    • None
    • None
    • Hide

      To reproduce:
      1) Create a Hello World sample application (Drools Eclipse Plugin)
      2) Replace Sample.drl with:
      declare Message
      @role(event)
      end

      rule "Hello World"
      when
      m : Message( myMessage : message )
      then
      System.out.println( myMessage );
      end

      //counts numbers of events in the previous 3 seconds
      rule "slidingTimeCount"
      when
      $n: Number (intValue > 0) from accumulate ( $e : Message() over window:time(3s) , count($e))
      then
      System.out.println("Messages in last 3 seconds: " + $n);
      end

      3) Add this constructor to the Message class:
      public Message(String m)

      { this.message = m; }

      4) In Main Method replace everything between //go and logger.close(); with:
      for(int i=1;i<3;i++)

      { Thread.sleep(1001); Message message = new Message("Hello" + i); ksession.insert(message); System.out.println(i + ". rule invocation"); ksession.fireAllRules(); }

      Thread.sleep(3001);

      Message lateMessage = new Message("Hello 3");
      ksession.insert(lateMessage);
      System.out.println(3 + ". rule invocation");
      ksession.fireAllRules();

      Thread.sleep(3001);
      Message lateMessage2 = new Message("Hello 4");
      ksession.insert(lateMessage2);
      System.out.println(4 + ". rule invocation");
      ksession.fireAllRules();

      --> Run: The output will be:
      1. rule invocation
      Messages in last 3 seconds: 1
      Hello1
      2. rule invocation
      Hello2
      Messages in last 3 seconds: 2
      3. rule invocation
      Messages in last 3 seconds: 1
      Hello 3
      Messages in last 3 seconds: 1
      4. rule invocation
      Messages in last 3 seconds: 1
      Hello 4

      --> After "5. rule invocation" the sliding-window rule fires 2x -> it should only fire once!

      More info:

      • if sleep time of thread is < 2997 in any Thread.sleep() after the loop, rule is not fired twice
      • bug also appears when working with SessionPseudoClock.advanceTime() instead of Thread.sleep() (also when t > 2997)
      • bug appears in STREAM mode and CLOUD mode

      The bug has some more quirks, e.g. somehow the condition in the erroneous firing rule seems not to work properly. For more information about the bug read this thread: http://drools.46999.n3.nabble.com/Getting-data-from-a-database-My-SQL-to-Guvnor-tt4025814.html#a4025870 (from post #2, thread was unintentionally hijacked)

      Show
      To reproduce: 1) Create a Hello World sample application (Drools Eclipse Plugin) 2) Replace Sample.drl with: declare Message @role(event) end rule "Hello World" when m : Message( myMessage : message ) then System.out.println( myMessage ); end //counts numbers of events in the previous 3 seconds rule "slidingTimeCount" when $n: Number (intValue > 0) from accumulate ( $e : Message() over window:time(3s) , count($e)) then System.out.println("Messages in last 3 seconds: " + $n); end 3) Add this constructor to the Message class: public Message(String m) { this.message = m; } 4) In Main Method replace everything between //go and logger.close(); with: for(int i=1;i<3;i++) { Thread.sleep(1001); Message message = new Message("Hello" + i); ksession.insert(message); System.out.println(i + ". rule invocation"); ksession.fireAllRules(); } Thread.sleep(3001); Message lateMessage = new Message("Hello 3"); ksession.insert(lateMessage); System.out.println(3 + ". rule invocation"); ksession.fireAllRules(); Thread.sleep(3001); Message lateMessage2 = new Message("Hello 4"); ksession.insert(lateMessage2); System.out.println(4 + ". rule invocation"); ksession.fireAllRules(); --> Run: The output will be: 1. rule invocation Messages in last 3 seconds: 1 Hello1 2. rule invocation Hello2 Messages in last 3 seconds: 2 3. rule invocation Messages in last 3 seconds: 1 Hello 3 Messages in last 3 seconds: 1 4. rule invocation Messages in last 3 seconds: 1 Hello 4 --> After "5. rule invocation" the sliding-window rule fires 2x -> it should only fire once! More info: if sleep time of thread is < 2997 in any Thread.sleep() after the loop, rule is not fired twice bug also appears when working with SessionPseudoClock.advanceTime() instead of Thread.sleep() (also when t > 2997) bug appears in STREAM mode and CLOUD mode The bug has some more quirks, e.g. somehow the condition in the erroneous firing rule seems not to work properly. For more information about the bug read this thread: http://drools.46999.n3.nabble.com/Getting-data-from-a-database-My-SQL-to-Guvnor-tt4025814.html#a4025870 (from post #2, thread was unintentionally hijacked)

      Given the following rule:

      //counts numbers of events in the previous 3 seconds
      rule "slidingTimeCount"
      when
      $n: Number (intValue > 0) from accumulate ( $e : Message() over window:time(3s) , count($e))
      then
      System.out.println("Messages in last 3 seconds: " + $n);
      end

      When Messages (Event) are inserted in a loop and after this loop fireAllRules() on the session is invoked, the rule fires twice.

            mfusco@redhat.com Mario Fusco
            amarok_jira Alexander Wolf (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: