<div dir="ltr">Hi Tim,<div>I know that you posted these through nabble, and it&#39;s not necessarily propagating your message to the community.  I have gotten a good response by registering for the mailing list and sending messages directly to <span style="font-family:arial,sans-serif;font-size:13px;white-space:nowrap">Rules Users List &lt;<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&gt;.  </span></div>
<div style><span style="font-family:arial,sans-serif;font-size:13px;white-space:nowrap">I am replying to your message through the rules-users mailing list - this way everyone on the list will definitely see your post.</span></div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Feb 8, 2013 at 9:08 AM, tslonaker <span dir="ltr">&lt;<a href="mailto:tslonaker+drools@gmail.com" target="_blank">tslonaker+drools@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I am new to Drools and I am struggling with this ruleflow issue.  Please let<br>
me know if I have been posting this info to the wrong message board.<br>
<br>
My situation is that I am working on converting our application from using<br>
an expensive commercial rule engine to Drools.  Our rule engine<br>
implementation uses a stateless server and it heavily depends on ruleflows.<br>
We could develop the rules using salience but that isn&#39;t ideal.<br>
<br>
It seems to me that there is still a bug in drools-server when using<br>
ruleflows in a stateless session.  It seems that the fix for  issue 2718<br>
&lt;<a href="https://issues.jboss.org/browse/JBRULES-2718" target="_blank">https://issues.jboss.org/browse/JBRULES-2718</a>&gt;   partially fixed the<br>
problem.  There is an easy workaround if you are coding your solution in<br>
Java.  You just create a new instance of the Stateless session every time.<br>
But in drools-server I don’t have any control over that.<br>
<br>
<br>
tslonaker wrote<br>
<div><div class="h5">&gt; I found a much easier way to recreate the problem described in my previous<br>
&gt; post.  I believe I have also found the root cause of the problem.  Below<br>
&gt; are the steps to recreate the issue:<br>
&gt;<br>
&gt; - Create a simple ruleflow and rules and compile them into a rule package.<br>
&gt; - In code create a stateless session<br>
&gt; - In a loop<br>
&gt;     o Create a fact<br>
&gt;     o Create a new execution batch with the following commands<br>
&gt;         - Insert the fact from above<br>
&gt;         - Start Process<br>
&gt;         - Fire All Rules<br>
&gt;         - Get Objects<br>
&gt;     o Execute the batch<br>
&gt;     o Check the results (number of rules that ran)<br>
&gt;<br>
&gt; I posted before that the problem didn’t happen while executing locally<br>
&gt; (not in drools server).  I didn’t realize this before, but adding a loop<br>
&gt; that executes the rules multiple times with the same session recreates the<br>
&gt; problem.<br>
&gt;<br>
&gt; Below is code that will recreate the issue.  Notice that the code below<br>
&gt; creates one instance of ksession and reuses it in the loop.<br>
&gt;<br>
&gt;       //Setup<br>
&gt;       KnowledgeBuilder kbuilder =<br>
&gt; KnowledgeBuilderFactory.newKnowledgeBuilder();<br>
&gt;<br>
&gt;       //The package includes the ruleflow<br>
&gt;       kbuilder.add( ResourceFactory.newFileResource(<br>
&gt; (&quot;YourRulePackage_WithRuleflow.pkg&quot;) ), ResourceType.PKG );<br>
&gt;       KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();<br>
&gt;       kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );<br>
*<br>
&gt;       //Create the stateless knowledge session outside the for loop<br>
&gt;       StatelessKnowledgeSession ksession =<br>
&gt; kbase.newStatelessKnowledgeSession();<br>
*<br>
&gt;<br>
&gt;       //Loop through executing the rules with the same data 3 times<br>
&gt;       for (int x = 0; x &lt; 3; x++)<br>
&gt;       {<br>
&gt;               //Create a new instance of the input fact<br>
&gt;               FactType inputDataType = kbase.getFactType(&quot;SimpleRuleflowTest&quot;,<br>
&gt; &quot;Input&quot;);<br>
&gt;               Object inputData = inputDataType.newInstance();<br>
&gt;               inputDataType.set(inputData, &quot;Name&quot;, &quot;Test data&quot;);<br>
&gt;<br>
&gt;               //Create a new instance of the command list<br>
&gt;               List cmds = new ArrayList();<br>
&gt;               cmds.add( CommandFactory.newInsert( inputData ));<br>
&gt;               cmds.add( CommandFactory.newStartProcess( &quot;TestRuleflow&quot;));<br>
&gt;               cmds.add( CommandFactory.newFireAllRules(&quot;rules&quot;));<br>
&gt;               cmds.add( CommandFactory.newGetObjects(&quot;output&quot;));<br>
&gt;<br>
&gt;               //Execute the rules<br>
&gt;               ExecutionResults results = ksession.execute(<br>
&gt; CommandFactory.newBatchExecution( cmds ) );<br>
&gt;<br>
&gt;               //Get the number of rules that ran<br>
&gt;               Object rules = results.getValue(&quot;rules&quot;);<br>
&gt;               System.out.println(&quot;Rules that ran:  &quot; + rules.toString());<br>
&gt;       }<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; Each iteration through the loop should fire 3 rules.  Running the code<br>
&gt; above you should get the following output:<br>
&gt;<br>
&gt;        Rules that ran:  3<br>
&gt;        Rules that ran:  1<br>
&gt;        Rules that ran:  1<br>
&gt;<br>
&gt;<br>
&gt; I spent several hours researching the drools source code and I believe I<br>
&gt; have found the problem.  What I have found is related to<br>
&gt; Issue 2718 &lt;<a href="https://issues.jboss.org/browse/JBRULES-2718" target="_blank">https://issues.jboss.org/browse/JBRULES-2718</a>&gt;<br>
&gt; .<br>
&gt; Check out the change made for this issue:<br>
&gt; 2718 fix<br>
&gt; &lt;<a href="https://source.jboss.org/viewrep/Drools/drools-core/src/main/java/org/drools/impl/StatelessKnowledgeSessionImpl.java?r1=63021da325036ec6fbdf4019e8c8293db21555ec&amp;r2=fad9b951f44ac813e5faf50f097335c2a97007ae" target="_blank">https://source.jboss.org/viewrep/Drools/drools-core/src/main/java/org/drools/impl/StatelessKnowledgeSessionImpl.java?r1=63021da325036ec6fbdf4019e8c8293db21555ec&amp;r2=fad9b951f44ac813e5faf50f097335c2a97007ae</a>&gt;<br>

&gt; .<br>
&gt;<br>
&gt; Below is a snippet from the code that was modified for issue 2718.  The<br>
&gt; “if (!initialized)” block was added.  The code loops through event<br>
&gt; listeners on the wm object and adds them to the stateless session’s<br>
&gt; listeners.  This works fine for the first rule execution.  But the next<br>
&gt; rule execution creates a new instance for wm.  Therefore it also creates<br>
&gt; new instances of listeners for wm.  So we have a new instance of wm and<br>
&gt; the stateless session is pointing to the old listeners from the first<br>
&gt; instance of wm.  I believe that is why it only runs correctly one time. It<br>
&gt; seems that that the “if (!initialized)” block of code needs to execute<br>
&gt; every time newWorkingMemory() is called.<br>
&gt;<br>
&gt;       public StatefulKnowledgeSession newWorkingMemory() {<br>
&gt;               :<br>
&gt;               :<br>
&gt;               ReteooWorkingMemory wm = new ReteooWorkingMemory(<br>
&gt; this.ruleBase.nextWorkingMemoryCounter(),<br>
&gt;                                                                                                                 this.ruleBase,<br>
&gt;                                                                                                                 (SessionConfiguration) this.conf,<br>
&gt;                                                                                                                 this.environment );<br>
&gt;               :<br>
&gt;               :<br>
&gt;<br>
*<br>
&gt; if (!initialized) {<br>
*<br>
&gt;                       // copy over the default generated listeners that are used for internal<br>
&gt; stuff once<br>
&gt;                       for (org.drools.event.AgendaEventListener listener:<br>
&gt; wm.getAgendaEventSupport().getEventListeners()) {<br>
&gt;                               this.agendaEventSupport.addEventListener(listener);<br>
&gt;                       }<br>
&gt;                       for (org.drools.event.WorkingMemoryEventListener listener:<br>
&gt; wm.getWorkingMemoryEventSupport().getEventListeners()) {<br>
&gt;                               this.workingMemoryEventSupport.addEventListener(listener);<br>
&gt;                       }<br>
&gt;                       InternalProcessRuntime processRuntime = wm.getProcessRuntime();<br>
&gt;                       if (processRuntime != null) {<br>
&gt;                               for (ProcessEventListener listener:<br>
&gt; processRuntime.getProcessEventListeners()) {<br>
&gt;                                       this.processEventSupport.addEventListener(listener);<br>
&gt;                               }<br>
&gt;                       }<br>
&gt;                       initialized = true;<br>
&gt;               }<br>
&gt;               :<br>
&gt;               :<br>
&gt;       }<br>
&gt;<br>
&gt;<br>
&gt; So, I tested this theory in my test function.  I used reflection to flip<br>
&gt; the “initialized” flag at the bottom of my loop.  I did this to force the<br>
&gt; listeners of the stateless session to be refreshed for every execute call.<br>
&gt; It worked!  The other nodes in the ruleflow now get executed after the<br>
&gt; first rule execution.  Below is a snippet of my modified test code:<br>
&gt;<br>
&gt;<br>
&gt;        //Same As Above<br>
&gt;        :<br>
&gt;        :<br>
&gt;        //Create the stateless knowledge session outside the for loop<br>
&gt;        StatelessKnowledgeSession ksession =<br>
&gt; kbase.newStatelessKnowledgeSession();<br>
&gt;<br>
&gt;        //Loop through executing the rules with the same data 3 times<br>
&gt;        for (int x = 0; x &lt; 3; x++)<br>
&gt;        {<br>
&gt;               :<br>
&gt;               :<br>
&gt;               //Flip the initialized flag to false through reflection<br>
*<br>
&gt;               Field field =<br>
&gt; StatelessKnowledgeSessionImpl.class.getDeclaredField(&quot;initialized&quot;);<br>
&gt;               field.setAccessible(true);<br>
&gt;               field.setBoolean(ksession, false);<br>
*<br>
&gt;        }<br>
&gt;<br>
&gt;<br>
&gt; Running the code above you should get the following output:<br>
&gt;<br>
&gt;        Rules that ran:  3<br>
&gt;        Rules that ran:  3<br>
&gt;        Rules that ran:  3<br>
&gt;<br>
&gt; My original problem deals with drools-server.  It isn’t possible for me to<br>
&gt; flip the initialized flag to false in that scenario.  So, is there any<br>
&gt; sort of workaround that would get me past this issue when using<br>
&gt; drools-server?<br>
<br>
<br>
<br>
<br>
<br>
--<br>
</div></div>View this message in context: <a href="http://drools.46999.n3.nabble.com/Ruleflow-not-working-with-stateless-session-in-drools-server-5-5-0-Final-tp4021624p4022161.html" target="_blank">http://drools.46999.n3.nabble.com/Ruleflow-not-working-with-stateless-session-in-drools-server-5-5-0-Final-tp4021624p4022161.html</a><br>

<div class="HOEnZb"><div class="h5">Sent from the Drools: User forum mailing list archive at Nabble.com.<br>
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a></div></div></blockquote></div><br></div></div>