Hi Tim,
I know that you posted these through nabble, and it'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 Rules Users List <rules-users@lists.jboss.org>.  
I am replying to your message through the rules-users mailing list - this way everyone on the list will definitely see your post.


On Fri, Feb 8, 2013 at 9:08 AM, tslonaker <tslonaker+drools@gmail.com> wrote:
I am new to Drools and I am struggling with this ruleflow issue.  Please let
me know if I have been posting this info to the wrong message board.

My situation is that I am working on converting our application from using
an expensive commercial rule engine to Drools.  Our rule engine
implementation uses a stateless server and it heavily depends on ruleflows.
We could develop the rules using salience but that isn't ideal.

It seems to me that there is still a bug in drools-server when using
ruleflows in a stateless session.  It seems that the fix for  issue 2718
<https://issues.jboss.org/browse/JBRULES-2718>   partially fixed the
problem.  There is an easy workaround if you are coding your solution in
Java.  You just create a new instance of the Stateless session every time.
But in drools-server I don’t have any control over that.


tslonaker wrote
> I found a much easier way to recreate the problem described in my previous
> post.  I believe I have also found the root cause of the problem.  Below
> are the steps to recreate the issue:
>
> - Create a simple ruleflow and rules and compile them into a rule package.
> - In code create a stateless session
> - In a loop
>     o Create a fact
>     o Create a new execution batch with the following commands
>         - Insert the fact from above
>         - Start Process
>         - Fire All Rules
>         - Get Objects
>     o Execute the batch
>     o Check the results (number of rules that ran)
>
> I posted before that the problem didn’t happen while executing locally
> (not in drools server).  I didn’t realize this before, but adding a loop
> that executes the rules multiple times with the same session recreates the
> problem.
>
> Below is code that will recreate the issue.  Notice that the code below
> creates one instance of ksession and reuses it in the loop.
>
>       //Setup
>       KnowledgeBuilder kbuilder =
> KnowledgeBuilderFactory.newKnowledgeBuilder();
>
>       //The package includes the ruleflow
>       kbuilder.add( ResourceFactory.newFileResource(
> ("YourRulePackage_WithRuleflow.pkg") ), ResourceType.PKG );
>       KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
>       kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
*
>       //Create the stateless knowledge session outside the for loop
>       StatelessKnowledgeSession ksession =
> kbase.newStatelessKnowledgeSession();
*
>
>       //Loop through executing the rules with the same data 3 times
>       for (int x = 0; x < 3; x++)
>       {
>               //Create a new instance of the input fact
>               FactType inputDataType = kbase.getFactType("SimpleRuleflowTest",
> "Input");
>               Object inputData = inputDataType.newInstance();
>               inputDataType.set(inputData, "Name", "Test data");
>
>               //Create a new instance of the command list
>               List cmds = new ArrayList();
>               cmds.add( CommandFactory.newInsert( inputData ));
>               cmds.add( CommandFactory.newStartProcess( "TestRuleflow"));
>               cmds.add( CommandFactory.newFireAllRules("rules"));
>               cmds.add( CommandFactory.newGetObjects("output"));
>
>               //Execute the rules
>               ExecutionResults results = ksession.execute(
> CommandFactory.newBatchExecution( cmds ) );
>
>               //Get the number of rules that ran
>               Object rules = results.getValue("rules");
>               System.out.println("Rules that ran:  " + rules.toString());
>       }
>
>
>
> Each iteration through the loop should fire 3 rules.  Running the code
> above you should get the following output:
>
>        Rules that ran:  3
>        Rules that ran:  1
>        Rules that ran:  1
>
>
> I spent several hours researching the drools source code and I believe I
> have found the problem.  What I have found is related to
> Issue 2718 <https://issues.jboss.org/browse/JBRULES-2718>
> .
> Check out the change made for this issue:
> 2718 fix
> <https://source.jboss.org/viewrep/Drools/drools-core/src/main/java/org/drools/impl/StatelessKnowledgeSessionImpl.java?r1=63021da325036ec6fbdf4019e8c8293db21555ec&r2=fad9b951f44ac813e5faf50f097335c2a97007ae>
> .
>
> Below is a snippet from the code that was modified for issue 2718.  The
> “if (!initialized)” block was added.  The code loops through event
> listeners on the wm object and adds them to the stateless session’s
> listeners.  This works fine for the first rule execution.  But the next
> rule execution creates a new instance for wm.  Therefore it also creates
> new instances of listeners for wm.  So we have a new instance of wm and
> the stateless session is pointing to the old listeners from the first
> instance of wm.  I believe that is why it only runs correctly one time. It
> seems that that the “if (!initialized)” block of code needs to execute
> every time newWorkingMemory() is called.
>
>       public StatefulKnowledgeSession newWorkingMemory() {
>               :
>               :
>               ReteooWorkingMemory wm = new ReteooWorkingMemory(
> this.ruleBase.nextWorkingMemoryCounter(),
>                                                                                                                 this.ruleBase,
>                                                                                                                 (SessionConfiguration) this.conf,
>                                                                                                                 this.environment );
>               :
>               :
>
*
> if (!initialized) {
*
>                       // copy over the default generated listeners that are used for internal
> stuff once
>                       for (org.drools.event.AgendaEventListener listener:
> wm.getAgendaEventSupport().getEventListeners()) {
>                               this.agendaEventSupport.addEventListener(listener);
>                       }
>                       for (org.drools.event.WorkingMemoryEventListener listener:
> wm.getWorkingMemoryEventSupport().getEventListeners()) {
>                               this.workingMemoryEventSupport.addEventListener(listener);
>                       }
>                       InternalProcessRuntime processRuntime = wm.getProcessRuntime();
>                       if (processRuntime != null) {
>                               for (ProcessEventListener listener:
> processRuntime.getProcessEventListeners()) {
>                                       this.processEventSupport.addEventListener(listener);
>                               }
>                       }
>                       initialized = true;
>               }
>               :
>               :
>       }
>
>
> So, I tested this theory in my test function.  I used reflection to flip
> the “initialized” flag at the bottom of my loop.  I did this to force the
> listeners of the stateless session to be refreshed for every execute call.
> It worked!  The other nodes in the ruleflow now get executed after the
> first rule execution.  Below is a snippet of my modified test code:
>
>
>        //Same As Above
>        :
>        :
>        //Create the stateless knowledge session outside the for loop
>        StatelessKnowledgeSession ksession =
> kbase.newStatelessKnowledgeSession();
>
>        //Loop through executing the rules with the same data 3 times
>        for (int x = 0; x < 3; x++)
>        {
>               :
>               :
>               //Flip the initialized flag to false through reflection
*
>               Field field =
> StatelessKnowledgeSessionImpl.class.getDeclaredField("initialized");
>               field.setAccessible(true);
>               field.setBoolean(ksession, false);
*
>        }
>
>
> Running the code above you should get the following output:
>
>        Rules that ran:  3
>        Rules that ran:  3
>        Rules that ran:  3
>
> My original problem deals with drools-server.  It isn’t possible for me to
> flip the initialized flag to false in that scenario.  So, is there any
> sort of workaround that would get me past this issue when using
> drools-server?





--
View this message in context: http://drools.46999.n3.nabble.com/Ruleflow-not-working-with-stateless-session-in-drools-server-5-5-0-Final-tp4021624p4022161.html
Sent from the Drools: User forum mailing list archive at Nabble.com.

_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users