Richard,

   There are some misconceptions in your example. I will try to clarify some things:

1. The Ruleflow: every time you call "ksession.startProcess("myflow");", you start a new flow instance (or process instance if you prefer). For each instance, it will activate in turn your groups one, two and three, moving to the next group when no more activations exist. Although, you didn't tie you facts/rules to any particular instance, meaning you have a "pool of facts" and a "pool of flow instances" that are all matching themselves in no specific way. In other words, you are inserting messages and starting flows 50 times in your example. Imagine that when the flow instance #20 reaches node "three", you are at the same time inserting message #30... message number #30 will activate the rule "NotThree" and it will fire as part of the flow instance #20... you will have your "strange" behaviors.

2. On top of the situation above, you are firing rules with fireUntilHalt(), meaning the engine is running in asynchronous, reactive mode, and you will have no control at all over the results you are getting back.

3. Since you mentioned fusion on the subject of this message, I guess you are probably setting the message role as "event", and in stream mode, the engine will try to determine when a fact is no longer needed and can be automatically expired. Although, at the same time, you are trying to retract the event in rules of group "three". Since the fact might have been already expired by that time, you are getting the consequence exception saying the fact is no longer in the working memory.

   I guess what I am saying is: all these features in Drools are there for a reason, and it is possible to mistakenly try to use them for things they are not intended to. The only way to prevent that is by educating users. If the documentation is not clear, please help us make it better.

   Back to your example, first things first: simplify it...

* do you really need the engine to run it in reactive mode? try batching facts and fire rules in a more controlled manner. Single thread is, as you know, a lot easier to deal with than multi-threads.

* do you need to have all your events in the same session? If you can have one session per "request", your flow+rules+events will work as you expect. If you need to have all events and flow and rules in the same session, then you need to tie rules to flow instances using process variables, possibly also using goal facts to drive your progress, etc.

* do you really need events and stream mode? cloud mode (default) is much easier to understand and deal with, since there is no automatic garbage collection, session clock requirements, etc.

   Hope it helps,
       Edson

2009/12/17 RichardA <Richard.Ambridge@sun.com>

Hi all again,
I am having a problem where the results of the rules is not consistent.
I am using rules flow and fireUntilHalt..

Here is most of my code: (expanding the default drools example)

private static KnowledgeBase readKnowledgeBase() throws Exception {
               KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
               kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"),
ResourceType.DRL);
               kbuilder.add(ResourceFactory.newClassPathResource("Flow.rf"),
ResourceType.DRF);
               KnowledgeBuilderErrors errors = kbuilder.getErrors();
               if (errors.size() > 0) {
                       for (KnowledgeBuilderError error: errors) {
                               System.err.println(error);
                       }
                       throw new IllegalArgumentException("Could not parse knowledge.");
               }
               KnowledgeBaseConfiguration conf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
               conf.setOption(EventProcessingOption.STREAM);
               KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(conf);
               kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
               return kbase;
       }

public static final void main(String[] args) {
               try {
                       // load up the knowledge base
                       KnowledgeBase kbase = readKnowledgeBase();
                       final StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();
                       new Thread(new Runnable() {
             public void run() {
                         ksession.fireUntilHalt();
                     }
                   }, "FireAllRules").start();
                       // go !
                       for(int i=0;i<50;i++){
                         Message message = new Message();
                         message.setMessage("one");
                         ksession.insert(message);
                         ksession.startProcess("myflow");
                       }
                       System.out.println("Sleeping");
                       Thread.sleep(20000);
                       System.out.println("Halt");
                       ksession.halt();
               } catch (Throwable t) {
                       t.printStackTrace();
               }
       }

So, notice fireUntilHalt is started in a thread.
And its in STREAM mode
and I use flow group and sample rules set.
Then inject 50 messages, and after each inject start the 'myflow'

The rule flow is like this;
Start->  One -> Two -> Three -> End

and the rules are:
rule "One"
   ruleflow-group "One"
       when
               m : Message( message=="one" )
       then

               m.setMessage( "two" );
               update( m );
end

rule "Two"
   ruleflow-group "Two"
       when
               m : Message( message=="two" )
       then
               m.setMessage( "three" );
               update( m );
end

rule "NotThree"
   ruleflow-group "Three"
       when
               m : Message( message!="three" )
       then
               System.out.println( "Message is not three????????????" );
               retract(m);
end
rule "Three"
   ruleflow-group "Three"
       when
               m : Message( message=="three" )
       then
               retract(m);
end


So, from that you should see that as an object is injected it has
message=="one"
so flow group One should match, the message updates to 'two'
then flow group two should match, message updates to 'three'
and then the group three rule Three should match and the object retracted.

Sometimes I run this I get results as expected.
Other times I get 1 message hit the 'NotThree' rule.
Other times I get lots of them hit the 'NotThree' rule.
Sometimes I get;
Exception in thread "FireAllRules"
org.drools.runtime.rule.ConsequenceException: org.drools.FactException:
Retract error: handle not found for object: null. Is it in the working
memory?
       at
org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:23)


Its driving me mad as my project is failing due to inconsistent results.
Please help..

--
View this message in context: http://n3.nabble.com/Inconsistent-results-in-fusion-tp93259p93259.html
Sent from the Drools - User mailing list archive at Nabble.com.
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users



--
 Edson Tirelli
 JBoss Drools Core Development
 JBoss by Red Hat @ www.jboss.com