无状态与流氓中的有状态会话行为

时间:2016-10-22 20:25:18

标签: drools

我是流口水的新手。我试图理解Drools提供的无状态和有状态会话之间的区别。

按照我最初的理解,

如果是无状态会话,如果在任何规则的操作执行期间修改了事实,则不会将其重新提交给推理引擎以找出与修改后的事实匹配的新规则。

如果是有状态会话,如果在任何规则的操作执行期间修改了事实,那么它将被重新提交给推理引擎,以找出与修改后的事实匹配的新规则,然后执行相应的操作。 / p>

因此,当我尝试通过编写示例规则来验证此行为时,我发现两种情况下的行为完全相同。所以现在我对有状态会话和无状态会话之间的区别感到困惑。

我想请大家帮助我理解有状态和无状态会话的正确行为。

为了您的参考,我将粘贴有状态和无状态会话的示例代码及其输出和示例规则。

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

输入对象(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(无状态会话测试代码)

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);
    }

}

无状态会话测试代码的输出:

没有资格获得许可 设置Valid有效 第二条规则被解雇 更新的申请人=申请人[姓名= John Smith先生,年龄= 16,有效=错误]

StatefulSessionExample.java(无状态会话测试代码)

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);
    }

}

有状态会话测试代码的输出:

没有资格获得许可 设置Valid有效 第二条规则被解雇 更新的申请人=申请人[姓名= John Smith先生,年龄= 16,有效=错误]

再次要求每个人帮助我理解有状态和无状态会话的正确行为。

提前致谢, Manish Gandhi

1 个答案:

答案 0 :(得分:0)

据我所知,当您在无状态会话中触发规则时,更改不会触发新规则。但这并不意味着规则不会因为变化而被解雇。第一个规则更改有效值,这意味着当您检查第二个规则的条件时,有效已经为假并且规则触发。

如果更改影响了上一个规则的“何时”部分,则在无状态会话中,第一个规则将不会被第二次触发,而第一个规则将在第一个规则中触发。