web-dev-qa-db-ja.com

よだれのアジェンダグループを理解する

サンプルの例を試して、アジェンダグループがどのように機能するかを確認しました。最初に、ksessionのフォーカスをアジェンダグループ「ag1」に設定し、ルールを実行しました。

package com.sample

import com.sample.DroolsTest.Message;

rule "Hello World"
  agenda-group "ag1"
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println( "Hello World" ); 
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

rule "Hello World 2"
  agenda-group "ag2"
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println( "Hello World 2" ); 
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

rule "GoodBye"
  agenda-group "ag1"
    when
        m : Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( "GoodBye" );
        drools.setFocus("ag2");
        System.out.println("comeon man");
        m.setStatus(com.sample.DroolsTest.Message.HELLO);
        update(m);
end

rule "GoodBye 2"
  agenda-group "ag2"
    when
        Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( "GoodBye 2" );
end

これは私が得た出力です。

Hello World
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
GoodBye 2
GoodBye
comeon man
Hello World 2
...
...

「GoodBye2」までの出力の最初の5行は理解できました。しかし、フォーカスが「ag2」に設定されたため、どのようにして「ag1」アジェンダグループの「GoodBye」ルールに戻り、再発しました。

ありがとう。

16
Manish Mulani

アジェンダグループはスタックのように機能します。特定のアジェンダグループにフォーカスを設定すると、そのグループはスタックの一番上に配置されます。エンジンが次のアクティベーションを起動しようとし、特定のグループにアクティベーションがなくなると、そのグループはスタックの最上位から削除され、その下のグループが再びフォーカスを受け取ります。

したがって、次のようになります(mainは常に存在するデフォルトのグループです):

* STACK: [MAIN, ag1]

Hello Word fires and activates both "GoodBye" rules
GoodBye fires, activates both "Hello World" rules and sets the focus to "ag2"

* STACK: [MAIN, ag1, ag2]

Hellow World 2 fires, cancels the "Hello World 1" rule and activates both "GoodBye" rules
GoodBye 2 fires because ag2 has the focus

* There are no more activations in ag2 to fire, so ag2 is removed from the stack
* STACK: [MAIN, ag1]
* The "GoodBye" rule is still active in ag1, so it fires

GoodBye fires, activates both "Hello World" rules and sets the focus to "ag2"

* STACK: [MAIN, ag1, ag2]

Hellow World 2 fires, cancels the "Hello World 1" rule and activates both "GoodBye" rules
...

そして、ループが繰り返されます。

この種の動作は、EclipseIDEで監査ログを使用すると非常に簡単に確認できます。

お役に立てれば。

24
Edson Tirelli

ルールの計算中にセッションでファクトを変更したため(メッセージオブジェクトはファクトに含まれていると思います)、Droolsナレッジベースを更新するために、所属するアジェンダグループに関係なく、他のルールが再度計算されます。 。

rule定義の後の行でこれを防ぐために、no-loop trueを追加できます。

よくわかりませんが、これはアプリで気付いた動作であり、無限ループを解決する必要があります。ちなみに、事実が変わったときにルールを再計算するのは理にかなっているようです。

1
Nicholas