frank
frank

Reputation: 1201

jboss drools, multiple same facts, fire rule only one time

i want to execute my rules, and my java code like :

Fact fact1 = new Fact(); 
fact1.setName("name1"); 
fact1.setValue("chn"); 
.... 

Fact fact2 = new Fact(); 
fact2.setName("name2"); 
fact2.setValue("chn"); 
.... 

List<Fact> facts = new ArrayList<Fact>(); 
facts.add(fact1); 
facts.add(fact2); 

ksession.execute(facts); 

my rules like : 

rule "rule1" 
    when 
        $partFact:Fact(value=="chn") 
    then 
        Action action = new Action(); 
        .... 
end 

rule "rule2" 
    when 
        $partFact:Fact(name=="name1") 
    then 
        Action action = new Action(); 
        .... 
end 

what i want are :

  1. rule1 and rule2 only one rule executed, that is if 'rule1' executed, then 'rule2' won't executed even meet 'rule2' conditions.

  2. each rule only executed one time, for example, there are 2 Fact, and all these 2 Fact satisfy 'rule1', but 'rule1' only executed one time, not 2 times.

how can i achieve my goals? thanks in advance.

Upvotes: 2

Views: 5354

Answers (3)

GauRang Omar
GauRang Omar

Reputation: 871

You can use "NO-LOOP" attribute. With "no-loop" attribute for each set of facts a rule is fires only once but the limitation is if you will modify the fact in any other rule group then those rules will be active again.

One solution you can try is the "lock-on-active" attribute to avoid infinite execution loops involving one or more rules. lock-on-active is kind of update of no-loop.

Lock-on-active is scoped by a rule-group and will prevent rules from re-firing as long as the group is focused. It does not depend on new facts, or updates to the existing ones, but only on the agenda focus. If you do not manipulate groups, this may be an option.

Upvotes: 0

Remi Morin
Remi Morin

Reputation: 292

One rule prevent other rule to get executed may be a symptom of silenced exception. Wrap rules execution into a catch clause. I debugged a case where one rule execution prevent other rules to get executed but this was because something was throwing inside rule execution, the exception stop the rule execution chain, and the exception was trapped elsewhere in the code. Long story short, isolate execution like that:

try {
    kieSession.fireAllRules();
} catch (Exception e) {
    LOGGER.error("Error on rules execution", e);
    ... re-throw or manage the exception
} 

The error will then be obvious. When running rules we have to expect exception!

Upvotes: -2

laune
laune

Reputation: 31300

Try these:

rule "rule1" 
    when 
        exists Fact(value=="chn") 
    then 
        Action action = new Action(); 
        .... 
end 

rule "rule2" 
    when
        not Fact(value=="chn")
        exists Fact(name=="name1") 
    then 
        Action action = new Action(); 
        .... 
end 

Upvotes: 1

Related Questions