0

我在尝试动态重新加载规则时遇到问题。从上下文开始:我们有 DRLs 文件,其中包含总共 10000 条规则和各种类型。由于编译和重新部署规则的过程开始变得很长(超过几分钟),我们希望只编译和重新部署修改后的规则。

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

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

我在查看 ReteoRuleBase 对象时发现,TypeDeclaration 列表包含两个以“Item”命名的类,这肯定是重新部署的规则与正确对象不匹配的原因。

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

    @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(第一次部署):

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

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

Object A -> C

知道我们如何处理这种不合并的类型吗?

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

4

1 回答 1

1

从 5.2 版开始,Drools 不支持重新部署类型声明。原因是在java中,一个类是通过classloader+class来标识的。部署类型声明时,将需要刷新类加载器,从而有效地创建新的类加载器。正如您所指出的,所有现有规则仍将期望旧的类加载器+类,并且不会匹配新的类加载器+类。

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

于 2011-08-31T20:41:39.833 回答