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

SegmentPropagator doesn't deal with tuple staged as update

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • None
    • None
    • None
    • None
    • 2022 Week 02-04 (from Jan 10)
    • NEW
    • NEW

      The following test case

       

          public static class Firings {
              private final List<String> list = new ArrayList<>();
              public List<String> getList() {
                  return list;
              }
          }
          @Test
          public void testPeerUpdate() {
              // DROOLS-6783
              final String str =
                      "import " + Firings.class.getCanonicalName() + "\n" +
                      "\n" +
                      "rule R1 when\n" +
                      "  Integer()\n" +
                      "  $f : Firings( list not contains \"R1\" )\n" +
                      "then\n" +
                      "  $f.getList().add(\"R1\");\n" +
                      "  update($f);\n" +
                      "end\n" +
                      "\n" +
                      "rule R2 agenda-group \"x\" when\n" +
                      "  Integer()\n" +
                      "  Firings( $l : list )\n" +
                      "  String()\n" +
                      "then\n" +
                      "end\n" +
                      "\n" +
                      "rule R3 agenda-group \"x\" when\n" +
                      "  Integer()\n" +
                      "  Firings( $l : list )\n" +
                      "then\n" +
                      "end\n" +
                      "\n" +
                      "rule R4 when\n" +
                      "  Integer()\n" +
                      "  Firings( $l : list )\n" +
                      "then\n" +
                      "end\n" +
                      "\n" +
                      "rule R5 when\n" +
                      "  Integer()\n" +
                      "  $f : Firings( list not contains \"R5\" )\n" +
                      "then\n" +
                      "  $f.getList().add(\"R5\");\n" +
                      "  update($f);\n" +
                      "end";
              KieBase kbase = KieBaseUtil.getKieBaseFromKieModuleFromDrl("test", kieBaseTestConfiguration, str);
              KieSession ksession = kbase.newKieSession();
              ksession.insert(1);
              ksession.insert(new Firings());
              ksession.getAgenda().getAgendaGroup("x").setFocus();
              assertEquals( 5, ksession.fireAllRules() );
          }
      

       

      causes this exception

       

      java.lang.IllegalStateException: It should not be possible that an existing udpate is staged, when an insert is later requested.
          at org.drools.core.phreak.SegmentPropagator.updateChildLeftTupleDuringInsert(SegmentPropagator.java:152)
          at org.drools.core.phreak.SegmentPropagator.processPeerInserts(SegmentPropagator.java:95)
          at org.drools.core.phreak.SegmentPropagator.processPeers(SegmentPropagator.java:69)
          at org.drools.core.phreak.SegmentPropagator.propagate(SegmentPropagator.java:45)
          at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:359)
          at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:181)
          at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:139)
          at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:234)
          at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:90)
          at org.drools.core.concurrent.AbstractRuleEvaluator.internalEvaluateAndFire(AbstractRuleEvaluator.java:33)
          at org.drools.core.concurrent.SequentialRuleEvaluator.evaluateAndFire(SequentialRuleEvaluator.java:43)
          at org.drools.kiesession.agenda.DefaultAgenda.fireLoop(DefaultAgenda.java:754)
          at org.drools.kiesession.agenda.DefaultAgenda.internalFireAllRules(DefaultAgenda.java:701)
          at org.drools.kiesession.agenda.DefaultAgenda.fireAllRules(DefaultAgenda.java:693)
          at org.drools.kiesession.session.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1092)
          at org.drools.kiesession.session.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1083)
          at org.drools.kiesession.session.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1067)
          at org.drools.mvel.integrationtests.session.UpdateTest.testPeerUpdate(UpdateTest.java:633)
      

       

      This is the detailed analysis of what happens

      1. JoinNodeLeftTuple[JoinNode(11)] has a peer RuleTerminalNodeLeftTuple[RuleTerminalNode(13): rule=R3]. Then it has a peer RuleTerminalNodeLeftTuple[RuleTerminalNode(14): rule=R4]
      2. When SegmentPropagator.processPeerInserts() is called, these 2 peers's stagedType are set to Tuple.UPDATE (at updateChildLeftTupleDuringInsert()).
      3. R4 is fired. So RuleTerminalNodeLeftTuple[RuleTerminalNode(14): rule=R4]'s stagedType is cleared at PhreakRuleTerminalNode.doLeftUpdates().
      4. However, PhreakRuleTerminalNode.doLeftUpdates() is not called for R3. So RuleTerminalNodeLeftTuple[RuleTerminalNode(13): rule=R3]'s stagedType remains Tuple.UPDATE.
      5. Next SegmentPropagator.processPeerInserts() -> updateChildLeftTupleDuringInsert() finds that RuleTerminalNodeLeftTuple[RuleTerminalNode(13): rule=R3]'s stagedType = Tuple.UPDATE. So results in the error.

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

                Created:
                Updated:
                Resolved: