Scala Drools规则不从Akka演员系统发射

Scala Drools规则不从Akka演员系统发射,scala,rest,akka,drools,actor,Scala,Rest,Akka,Drools,Actor,我们在Scala中构建了一个Drools模块,单独调用时运行良好,但是现在我们将它集成到Akka actor系统中,我们已经构建了该系统,能够通过REST调用触发规则 出于某种原因,没有任何规则触发,即使是空白规则,例如: rule "sample 1" salience 1000 auto-focus true when then System.out.println("Well, that finally worked!"); end

我们在Scala中构建了一个Drools模块,单独调用时运行良好,但是现在我们将它集成到Akka actor系统中,我们已经构建了该系统,能够通过REST调用触发规则

出于某种原因,没有任何规则触发,即使是空白规则,例如:

rule "sample 1"
    salience 1000
    auto-focus true
    when

    then
        System.out.println("Well, that finally worked!");
    end
容器、会话等看起来很好,对象(事实)被正确插入(通过检查事实计数进行验证)。(KieServices和KieContainer是在启动级别初始化的,即在创建参与者之前,并在以后的阶段使用。)奇怪的是,当运行
kieSession.fireallrules()
时,触发的规则总数始终为0,并且事实没有更新

使用Akka,我们通过REST发送JSON格式的对象(MyObject类型)。根据REST请求创建一个actor,并调用Drools模块,如下所示:

  • 创建了一个新的参与者来调用Drools引擎
  • 在引导级别使用KieServices集创建新的KieSession。[对于那些看过我之前文章的人,是的,下面是Scala代码]
val kieSession=DroolsMgt.getKieSession(List(“myFile.drl”),Boot.kieServices)
其中,
getKieSession
正在调用以下命令:

    val kfs = kieServices.newKieFileSystem()
    for (filename <- drlFiles) {
      val fis = new FileInputStream(filename)
      kfs.write(filename, kieServices.getResources.newInputStreamResource(fis))
    }

    val kieBuilder = kieServices.newKieBuilder(kfs).buildAll()

    val kieContainer = kieServices.newKieContainer(kieServices.getRepository.getDefaultReleaseId)

    kieContainer.newKieSession()

下面的代码不会解决您的问题,但它应该帮助您诊断您是否真的运行了规则以及您认为您执行的会话。我正在使用Java表示法

KieSession kieSession = ...
KieBase kieBase = kieSession.getKieBase();
Collection<KiePackage> kiePackages = kieBase.getKiePackages();
for( KiePackage kiePackage: kiePackages ){
    for( Rule rule: kiePackage.getRules() ){ 
        System.out.println( rule.getName() );
    }
}
KieSession KieSession=。。。
KieBase KieBase=kieSession.getKieBase();
集合kiePackages=kieBase.getKiePackages();
用于(基辅包基辅包:基辅包){
对于(规则:kiePackage.getRules()){
System.out.println(rule.getName());
}
}

这些类是线程安全的吗?参与者是唯一访问这些对象的人吗?Drools依赖于ThreadLocals吗?
KieContainer
是一个Java静态单例,如果您有一个长时间运行的会话,那么它也需要是单个实例。在Akka框架内,我可能会考虑创建一个singleton actor,加载它并控制对它的访问:我已经将问题缩小到调用
kieServices.getResources().newInputStreamResource(fis))
(其中fis是一个FileInputStream)时,drl文件没有转换为KieSources。我也更新了问题以反映这一点。仍然不能理解为什么它不能在这个模块中创建一个新的资源。我已经尝试了Scala等效的方法,使用
var kiePackages=kieBase.getKiePackages for(x println(“RULE FOUND\t”+y.getName))}
显然
。getPackages
显示有0个包可以开始。我在没有参与者的原始项目中尝试了相同的代码,包数为2,效果很好。这似乎就是问题所在。谢谢@laune!你知道为什么它不会加载包吗?你可以很容易地创建一个空的基库。您的系统如何为实际执行创建KieBase和KieSession?您是从DRL编译还是加载序列化的KieBase或KieSession?你有证据证明这有效吗?(你不仅仅是在如履薄冰,你还穿着热鞋来做这件事。)在我的问题中添加了一段代码,以显示我是如何创建这个会话的。当作为独立模块运行时,所有这些都可以正常工作。为什么要穿热鞋?我的工作方式有什么危险你可以考虑接受答案,然后打开一个新问题;
KieSession kieSession = ...
KieBase kieBase = kieSession.getKieBase();
Collection<KiePackage> kiePackages = kieBase.getKiePackages();
for( KiePackage kiePackage: kiePackages ){
    for( Rule rule: kiePackage.getRules() ){ 
        System.out.println( rule.getName() );
    }
}