如何使用已声明的事实类型来动态地重新加载规则? [英] How to dynamically reload rules using already declared fact types?

查看:201
本文介绍了如何使用已声明的事实类型来动态地重新加载规则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试动态重新加载规则时遇到问题。
从上下文开始:我们有DRLs文件,其中包含总共10000个规则,以及各种类型。随着编译和重新部署规则的过程开始很长(超过几分钟),我们想编译&重新部署只修改规则。

I am facing an issue while trying to reload rules dynamically. Starting with the context : we have DRLs files which contains a total of 10000 rules, and various types. As the process of compiling and redeploying rules is starting to be long (over than a couple of minutes), we would like to compile & redeploy ONLY the modified rule.

为了符合DRL,我们必须在DRL中声明重新部署修改后的规则和所有使用的类型。

To be DRL-compliant, we have to declare in the DRL to redeploy the modified rule, AND all used types.

我们的问题是在新的DRL中声明的类型不会与已部署的类型合并,所以新的规则在匹配这些类型时不会激活。

Our problem is that types declared in the new DRL are not merged with types already deployed, so new rules do not activate when matching those types.

我在查看ReteoRuleBase对象时发现,TypeDeclaration列表中包含两个以Item命名的类,这也是为什么重新部署的规则与正确的对象不匹配。

I found while looking at the ReteoRuleBase object that the list of TypeDeclaration contains two class named after "Item", and that's surely why the redeployed rule did not match the right object.

首先,我的单元测试暴露了我们部署和重新部署的方式:

First, my unit test exposing the way we deploy and redeploy :

    @Test
public void test_hot_deploy() throws FileNotFoundException {
    File drl1 = new File("src/test/resources/essai-drools/hot-deploy-1.drl"); 
    Resource resource1 = ResourceFactory.newInputStreamResource(new FileInputStream(drl1));

    File drl2 = new File("src/test/resources/essai-drools/hot-deploy-2.drl"); 
    Resource resource2 = ResourceFactory.newInputStreamResource(new FileInputStream(drl2));

    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    builder.add(resource1, ResourceType.DRL);
    KnowledgeBase kb = builder.newKnowledgeBase();
    StatefulKnowledgeSession session = kb.newStatefulKnowledgeSession();
    int fired = session.fireAllRules();
    Assert.assertEquals(2, fired);

            System.out.println("--- redeploy ---");

    KnowledgeBuilder builder2 = KnowledgeBuilderFactory.newKnowledgeBuilder();
    builder2.add(resource2, ResourceType.DRL);
    kb.addKnowledgePackages(builder2.getKnowledgePackages());

    session = kb.newStatefulKnowledgeSession();
    fired = session.fireAllRules();
    Assert.assertEquals(2, fired);
}

原始DRL(第一次部署):

The original DRL (the first deployed) :

package test;
declare Item
value : String
end
rule "insertion"
when
then
    Item $item = new Item();
    $item.setValue("A");
    insert($item);
    System.out.println("Object A inserted");
end
rule "modification"
when    
    $item: Item(value == "A")
then
    $item.setValue("B");
    update($item);
    System.out.println("Object A -> B");
end

重新部署的DRL:

package test;
declare Item
    value : String
end
rule "modification"
when    
    $item : Item(value == "A")
then
    $item.setValue("C");
    update($item);
    System.out.println("Object A -> C");
end

输出:

Object A inserted
Object A -> B
--- redeploy ---
Object A inserted

输出(如您所见,重新部署规则未执行)

The missing output (as you see, the redeploy rule was not executed)

Object A -> C

有什么想法可以处理这种不合并的类型?

Any idea of how we could deal with this type which do not merge ?

希望你有一个想法,我只是在这里提供信息。

Hope you got an idea, I am here for mere informations.

推荐答案

版本5.2,Drools不支持重新部署类型声明。原因是在java中,类被classloader + class识别。当部署类型声明时,它将需要刷新一个类加载器,有效地创建一个新的类加载器。正如你所注意到的,所有现有的规则仍然会期望旧的classloader +类,并且不会匹配新的classloader +类。

As of version 5.2, Drools does not support redeployment of type declarations. The reason is that in java, a class is identified by classloader+class. When a type declaration is deployed, it will require a classloader refresh, creating effectively a new classloader. As you've noted, all existing rules will still expect the old classloader+class and will not match the new classloader+class.

所以,我对你的建议是,如果您需要热重新部署规则,将类型声明保留在单独的DRL文件中,并且仅重新部署规则文件。或者,您可以即时生成新规则,或从文件中提取已更改的规则,仅重新部署它们。

So, my suggestion for you is, if you need to hot-redeploy rules, to keep your type declarations in a separate DRL file and only redeploy the rules files. Alternatively, you can generate the new rules on the fly or extract the changed rules from a file and only redeploy them.

这篇关于如何使用已声明的事实类型来动态地重新加载规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆