2

I am new to the drools. I was trying to understand the difference between Stateless and Stateful sessions provided by Drools.

As per my initial understanding,

In case of Stateless session, if fact is modified during action execution of any rule then it will not be re-submitted to inference engine to find out the new rules which matches the modified fact.

In case of Stateful session, if fact is modified during action execution of any rule then it will be re-submitted to inference engine to find out the new rules which matches the modified fact and then their corresponding action will be executed.

So when I tried to verify this behavior by writing a sample rule, I found that behavior is exactly same in both the cases. So now I am really confused regarding the difference between Stateful and Stateless sessions.

I would like to request everyone to help me in understand the correct behavior of Stateful and Stateless sessions.

For your reference I am pasting my sample code for Stateful and Stateless session along with their output and sample rule.

licenseApplication.drl   (Rule file)

package com.idal.droolsapp

rule "Is of valid age"
    no-loop
when
    $a : Applicant( age < 18 )
then
    System.out.println( "Not eligible for license" );
    System.out.println( "Setting Valid to false" );
    modify( $a ) { setValid( false ) };
end

rule "Is of valid false"
    salience 100
when
    $a : Applicant( valid == false )
then
    System.out.println( "Second rule fired" );
end

Input object (Fact) Applicant.java

package com.idal.droolsapp;

public class Applicant {

    private String name;

    private int age;

    private boolean valid = true;

    public Applicant(String name, int age) {
        setName(name);
        setAge(age);
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    public boolean isValid() {
        return valid;
    }

    @Override
    public String toString() {
        return "Applicant [name=" + name + ", age=" + age + ", valid=" + valid
                + "]";
    }


}

StatelessSessionExample.java (Stateless Session test code)

package com.idal.droolsapp;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatelessKnowledgeSession;

public class StatelessSessionExample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                .newKnowledgeBuilder();

        kbuilder.add(ResourceFactory.newClassPathResource(
                "licenseApplication.drl", StatelessSessionExample.class),

        ResourceType.DRL);

        if (kbuilder.hasErrors()) {

            System.err.println(kbuilder.getErrors().toString());

        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();

        Applicant applicant = new Applicant( "Mr John Smith", 16 );

        ksession.execute( applicant );

        System.out.println("Updated Applicant = " + applicant);
    }

}

Output of Stateless session test code:

Not eligible for license
Setting Valid to false
Second rule fired
Updated Applicant = Applicant [name=Mr John Smith, age=16, valid=false]

StatefulSessionExample.java (Stateless Session test code)

package com.idal.droolsapp;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class StatefulSessionExample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                .newKnowledgeBuilder();

        kbuilder.add(ResourceFactory.newClassPathResource(
                "licenseApplication.drl", StatefulSessionExample.class),

        ResourceType.DRL);

        if (kbuilder.hasErrors()) {

            System.err.println(kbuilder.getErrors().toString());

        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

        Applicant applicant = new Applicant( "Mr John Smith", 16 );

        ksession.insert( applicant );

        ksession.fireAllRules();

        ksession.dispose();

        System.out.println("Updated Applicant = " + applicant);
    }

}

Output of Stateful session test code:

Not eligible for license
Setting Valid to false
Second rule fired
Updated Applicant = Applicant [name=Mr John Smith, age=16, valid=false]

Once again requesting everyone to help me in understanding the correct behavior of Stateful and Stateless sessions.

Thanks in advance, Manish Gandhi

stop-cran
  • 4,229
  • 2
  • 30
  • 47

1 Answers1

0

As I understand it when you fire the rules in a stateless session, changes won't trigger new rules. But that doesn't mean that rules won't be fired because of changes. The first rule changes the value of valid, which means that by the time you check the second rule's condition valid is already false and the rules fires.

If the change affected the "when" part of the previous rule, in a stateless session the first rule wouldn't be triggered a second time, where in the first one it would.