0

ルールを動的にリロードしようとしているときに問題に直面しています。コンテキストから始めます。合計 10000 のルールとさまざまなタイプを含む DRL ファイルがあります。ルールのコンパイルと再デプロイのプロセスが長くなり始めているため (数分以上)、変更されたルールのみをコンパイルして再デプロイしたいと考えています。

DRL に準拠するには、DRL で宣言して、変更されたルールと使用されているすべての型を再デプロイする必要があります。

私たちの問題は、新しい DRL で宣言された型がすでにデプロイされている型とマージされないことです。そのため、それらの型に一致するときに新しいルールがアクティブになりません。

ReteoRuleBase オブジェクトを見ていると、TypeDeclaration のリストに「Item」にちなんで名付けられた 2 つのクラスが含まれていることがわかりました。これが、再デプロイされたルールが正しいオブジェクトと一致しなかった理由です。

まず、デプロイと再デプロイの方法を公開する単体テスト:

    @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 に答える