title: Why Drools is executing incorrect rules when multiple KieBase are executed in parallel?
body: <p>Drools seems to give incorrect results when multiple processes are run in parallel and in each process, a new <code>KieBase</code> object is created and processed every time.</p>
  
  <p>Tried with versions: <code>6.5.0.Final</code>, <code>7.32.0.Final</code></p>
  
  <p>Details:</p>
  
  <p>I executed 120 tasks in parallel (using 7 threads). Out of these 120 tasks, drools gave correct result for 108 tasks but executed incorrect rule for 12 tasks (no. of such failed tasks vary in each run). </p>
  
  <p>Let me post the code and output here:</p>
  
  <pre><code>    public class TempClass {
          public List&lt;String&gt; droolLogging = new ArrayList&lt;&gt;();
      }
  
     public void execute(){
          Map&lt;String, List&lt;String&gt;&gt; failedTasks = new ConcurrentHashMap&lt;&gt;(); // to see which tasks were incorrectly executed
  
          // Run 120 tasks in parallel using x threads (x depends upon no of processor)
  
          IntStream.range(1, 120).parallel()
          .forEach(taskCounter -&gt; {
  
              String uniqueId = "Task-"+taskCounter;
  
              TempClass classObj = new TempClass();
  
              String ruleString = "package com.sample" + taskCounter + "\n" +
                      "import com.TempClass\n" +
                      "\n" +\
                      "rule \"droolLogging"+taskCounter+"\"\n" +
                      "\t when \n" +
                      "\t\t obj: TempClass(true)\n" +
                      "\t then \n" +
                      "\t\t obj.droolLogging.add(\"RuleOf-"+uniqueId+"\");\n" +
                      "\t end\n";
  
              // Above ruleString contains 1 rule and it is always executed. 
              // After execution, it will add an entry in array list 'droolLogging' 
              // of class 'TempClass'. In this entry, we are storing task counter 
              // to see rule of which task is executed.
  
  
              //following line of code seems to be the culprit as this is somehow returning incorrect KieBase sometime.
  
              KieBase kbase = new KieHelper()
                               .addContent(ruleString, ResourceType.DRL)
                               .build();
  
          /*
          //Same issue occurs even if I create different file with different name instead of using KieHelper.
  
          KieServices ks = KieServices.Factory.get();
          KieFileSystem kfs = ks.newKieFileSystem();
  
          String inMemoryDrlFileName = "src/main/resources/inmemoryrules-" + taskCounter + ".drl";
  
          kfs.write(inMemoryDrlFileName, ruleString);
  
          KieBuilder kieBuilder = ks.newKieBuilder(kfs).buildAll();
          KieContainer kContainer = ks.newKieContainer(kieBuilder.getKieModule().getReleaseId());
          KieBaseConfiguration kbconf = ks.newKieBaseConfiguration();
          KieBase kbase = kContainer.newKieBase(kbconf);
          */
  
  
              StatelessKieSession kieSession = kbase.newStatelessKieSession();
              kieSession.execute(classObj);
  
              System.out.println("(" + Thread.currentThread().getName() + ") " +
                      uniqueId + "_" + classObj.droolLogging );
  
              //Important: 
              //  To see if correct rule is executed, task no. printed by variable 'droolLogging'
              //  should match with uniqueId
  
              if(classObj.droolLogging == null || classObj.droolLogging.size() != 1 ||
                      !classObj.droolLogging.get(0).endsWith(uniqueId)) {
                  failedTasks.put("" + taskCounter, classObj.droolLogging);
              }
          });
  
          logger.info("Failed:\n {}", failedTasks);
      }
  
  
  OUTPUT:
      (ForkJoinPool.commonPool-worker-1) Task-37_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-6) Task-8_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-3) Task-18_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-2) Task-108_[RuleOf-Task-4]
      (main) Task-78_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-7) Task-52_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-4) Task-97_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-5) Task-4_[RuleOf-Task-4]
      (ForkJoinPool.commonPool-worker-3) Task-19_[RuleOf-Task-19]
      (ForkJoinPool.commonPool-worker-5) Task-5_[RuleOf-Task-5]
      (ForkJoinPool.commonPool-worker-2) Task-109_[RuleOf-Task-109]
      (ForkJoinPool.commonPool-worker-7) Task-53_[RuleOf-Task-53]
      (ForkJoinPool.commonPool-worker-1) Task-38_[RuleOf-Task-38]
      (ForkJoinPool.commonPool-worker-4) Task-98_[RuleOf-Task-98]
      .... more
  
      Failed (12):
          {88=[RuleOf-Task-77], 78=[RuleOf-Task-4], 68=[RuleOf-Task-60], 37=[RuleOf-Task-4], 15=[RuleOf-Task-1], 18=[RuleOf-Task-4], 7=[RuleOf-Task-11], 8=[RuleOf-Task-4], 108=[RuleOf-Task-4], 71=[RuleOf-Task-76], 52=[RuleOf-Task-4], 97=[RuleOf-Task-4]}
  
  This shows:
  
   - Rule of task 77 was executed in task 88
   - Rule of task 4 was executed in task 78
   - Rule of task 60 was executed in task 68
   - ....
  
  This is wrong. For correct results, in each process, Rule of task X should be executed in task X only.
  </code></pre>
  
  <p>Any idea what can be the reason behind this ?</p>
  
  <hr>
  
  <p><strong>Update:</strong>
  Above code is just for testing purpose, to see how generation and execution of <code>KieBase</code> would behave in multi threaded environment. Actual use case is as follows:</p>
  
  <h2><strong>Use Case:</strong></h2>
  
  <p>We have a set of rules category wise. For each category, particular set of rules need to be executed.</p>
  
  <pre><code>Example:
  
   for category 1 , I need to execute rule101, rule102, rule103
  
   for category 2 , I need to execute rule201, rule202, rule203
   ....
  
   Note: During evaluation, rules of category X should NOT interfere with Rules of category Y, i.e., they should be run independently.
  </code></pre>
  
  <p>Since no. of categories are huge, we are building <code>KieBases</code> (for each category) in parallel and storing it for x minutes. After x minutes we check if rules have been changed for any category, if changed, <code>KieBase</code> is compiled again for those categories (which again would be in parallel).</p>
  
  <p>Also, new categories can be added at run time. So, for newly added categories as well, above procedure is followed.</p>
  
  <pre><code>   category1 -&gt; KieBase1   (compiled rules: rule101, rule102, rule103)
     category2 -&gt; KieBase2   (compiled rules: rule201, rule202, rule203)
     category3 -&gt; KieBase3
  
     Note: As already mentioned above, execution of KieBase X should NOT interfere with execution of KieBase Y as KieBases are created category wise and for each category, only particular set of rules should be executed.
  </code></pre>