【问题标题】:understanding agenda-group in drools了解流口水的议程组
【发布时间】:2011-10-15 18:13:07
【问题描述】:

我尝试了一个示例来了解议程组的工作原理。最初我将 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
...
...

在“GoodBye 2”之前,我可以理解输出的前 5 行。但是由于焦点设置为“ag2”,它是如何回到“ag1”议程组的“再见”规则并因此递归的。

谢谢。

【问题讨论】:

    标签: drools


    【解决方案1】:

    议程组的工作方式类似于堆栈。当您将焦点设置到给定议程组时,该组将放置在堆栈顶部。当引擎尝试触发下一个激活并且给定组中没有更多激活时,该组将从堆栈顶部移除,并且其下方的组再次获得焦点。

    所以它是这样的(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
    ...
    

    然后循环重复。

    如果你在 Eclipse IDE 中使用审计日志,这种行为是很容易看到的。

    希望这会有所帮助。

    【讨论】:

    • 如何激活这个审计日志?
    • 看看 session.addEventListener(new DebugAgendaEventListener())
    【解决方案2】:

    由于您在计算规则期间更改了会话中的事实(我猜您的 Message 对象在您的事实中),因此会再次计算其他规则,而不取决于它们所属的议程组,以便更新流口水知识库。

    您可以在rule 定义后添加no-loop true 以防止这种情况发生

    我不确定,但这是我在我的应用程序中注意到的行为,应该可以解决您的无限循环。顺便说一句,当事实发生变化时重新计算规则似乎是合乎逻辑的。

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2018-05-29
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多