2011-07-29 4 views
14

アジェンダグループがどのように機能するかのサンプルを試しました。最初は、ksessionの焦点をagenda-group "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 
... 
... 

「GoodBye 2」までの出力の最初の5行を理解できました。しかし、焦点が「ag2」に設定されているので、どのようにして「ag1」アジェンダグループの「GoodBye」ルールに戻って再帰しましたか?

ありがとうございました。

答えて

22

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

だから、この(メインは常に存在するデフォルト・グループである)のようになります:

* 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 
... 

、ループを繰り返します。

Eclipse IDEで監査ログを使用すると、この種の動作が非常に分かりやすくなります。

これが役に立ちます。

+0

この監査ログを有効にするにはどうすればよいですか? –

+0

session.addEventListener(new DebugAgendaEventListener())を見てください – Topera

1

ルールの計算中にセッション内のファクトを変更したため(メッセージオブジェクトはあなたの事実と同じです)、更新するために、ルールが属するアジェンダグループに依存せずに、再度計算されますDroolsの知識ベース。

あなたはrule定義

後の行にこれを防ぐためにno-loop trueを追加することができ、私は確かに静かではないんだけど、それは私が私のアプリに気づいたので、あなたの無限ループを解決しなければならない行動です。ところで、事実が変わったときにルールを再計算するのは理にかなっているようです。

関連する問題