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

Using queries in combination with agenda-groups leads to wrong firings

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 6.2.0.CR1
    • 6.1.0.Final, 6.2.0.Beta1
    • None
    • None

      When running the following test case:

          @Test
          public void testQueryWithAgendaGroup() {
              String drl =
                      "package org.drools.test; " +
                      "global java.util.List list; " +
      
                      "query foo( Integer $i ) " +
                      "   $i := Integer() " +
                      "end " +
      
                      "rule Detect " +
                      "agenda-group 'one' " +
                      "when " +
                      "   foo( $i ; ) " +
                      "then " +
                      "   list.add( $i ); " +
                      "end " +
      
                      "rule OnceMore " +
                      "agenda-group 'two' " +
                      "no-loop " +
                      "when " +
                      "   $i : Integer() " +
                      "then " +
                      "   update( $i );" +
                      "end " +
                      "";
      
              KieHelper helper = new KieHelper();
              helper.addContent( drl, ResourceType.DRL );
              KieSession kieSession = helper.build().newKieSession();
      
              List<Integer> list = new ArrayList<Integer>();
              kieSession.setGlobal( "list", list );
      
              FactHandle handle = kieSession.insert( 42 );
      
              Agenda agenda = kieSession.getAgenda();
              agenda.getAgendaGroup("two").setFocus();
              agenda.getAgendaGroup("one").setFocus();
      
              kieSession.fireAllRules();
              assertEquals( Arrays.asList( 42 ), list );
      
              kieSession.delete( handle );
      
              kieSession.insert( -99 );
      
              agenda.getAgendaGroup("two").setFocus();
              agenda.getAgendaGroup("one").setFocus();
      
              kieSession.fireAllRules();
              assertEquals( Arrays.asList( 42, -99 ), list );
          }
      

      The "Detect" rule, the one containing the query, fires twice with 42 even if the second time that fact shold be already been deleted. In particular the sequence of relevant events when running this test is the following:

      1. 1st fire, 42 updated
      1.1. process update in PhreakRuleTerminalNode of OnceMore
      1.1.1. blocked by no-loop
      1.2. process update in PhreakQueryTerminalNode
      1.2.1. update added to leftTupleSets of queryResult
      1.2.2. rule Detect doesn't fire again because it is in an inactive agenda-group

      2. 42 deleted
      2.1. the deleted factHandle refers to the RTNLeftTuple that is then added to the deleted leftTupleSets of the LIANode having as sink the RTN of rule OnceMore. Unfortunately there's no relationship between the deleted factHandle and the query activated by that fact.

      3. 2nd fire
      3.1. now AG "one" has focus so evaluates PhreakRuleTerminalNode of Detect using the updated leftTuple of point 1.2.1. - ERROR!!!
      3.2. process deleted 42 and inserted -99 in PhreakRuleTerminalNode of OnceMore
      3.3. process deleted 42 and inserted -99 in PhreakQueryTerminalNode, doesn't fire it because AG "one" is not active

            mfusco@redhat.com Mario Fusco
            mfusco@redhat.com Mario Fusco
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: