понимание повестки дня группы в слюнях - PullRequest
15 голосов
/ 29 июля 2011

Я попробовал пример примера, чтобы увидеть, как работает группа повестки дня. Первоначально я установил фокус 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
...
...

Я мог понять первые 5 строк вывода до "GoodBye 2". Но так как фокус был установлен на «ag2», как он вернулся к правилу «GoodBye» группы повестки дня «ag1» и, следовательно, повторился.

Спасибо.

Ответы [ 2 ]

23 голосов
/ 02 марта 2012

Группы повестки дня работают как стек. Когда вы устанавливаете фокус на данную группу повестки дня, эта группа помещается на вершину стека. Когда механизм пытается запустить следующую активацию, и в данной группе больше нет активаций, эта группа удаляется с вершины стека, и группа под ней снова получает фокус.

Таким образом, это выглядит так (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.

Надеюсь, это поможет.

1 голос
/ 02 марта 2012

Так как вы изменили факты в сеансе (я полагаю, ваш объект сообщения находится в ваших фактах) во время вычисления правила, другие правила вычисляются снова, независимо от группы повестки дня, к которой они принадлежат, чтобы обновить Слюни базы знаний.

Вы можете добавить no-loop true, чтобы предотвратить это в строке после rule определение

Я не совсем уверен, но это поведение, которое я заметил в моем приложении, и должно разрешить ваш бесконечный цикл. Кстати, кажется логичным снова вычислять правила при изменении фактов.

...