2011-07-29 13 views
14

Intenté un ejemplo de muestra para ver cómo funciona el grupo agenda. Inicialmente establecí el foco de ksession en el grupo de agenda "ag1" y activaba las reglas.entendiendo agenda-group en drools

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 

Esta es la salida que obtuve.

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

Pude entender las primeras 5 líneas de la salida hasta "GoodBye 2". Pero dado que el foco se configuró en "ag2", ¿cómo volvió a la regla "GoodBye" del grupo de agenda "ag1" y, por lo tanto, recursó?

Gracias.

Respuesta

22

Los grupos de programa funcionan como una pila. Cuando establece el foco en un grupo de agenda determinado, ese grupo se coloca en la parte superior de la pila. Cuando el motor intenta disparar la siguiente activación y no hay más activaciones en un grupo dado, ese grupo se elimina de la parte superior de la pila y el grupo debajo de él recibe el foco nuevamente.

Por lo tanto, dice así (principal es el grupo predeterminado que siempre está presente):

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

Y se repite el bucle.

Este tipo de comportamiento es muy fácil de ver si usa el registro de auditoría en el Eclipse IDE.

Espero que esto ayude.

+0

¿Cómo activar este registro de auditoría? –

+0

Eche un vistazo en session.addEventListener (nuevo DebugAgendaEventListener()) – Topera

1

Como cambiaste los hechos en la sesión (tu objeto Message está en tus hechos, supongo) durante el cálculo de una regla, otras reglas se vuelven a calcular, no dependiendo del grupo de agenda al que pertenecen, para actualizar la base de conocimiento Drools.

Se podría añadir no-loop true para evitar esto en la línea después rule definición

No estoy seguro de acallar, pero es el comportamiento me di cuenta en mi aplicación y debería resolver su modo de bucle infinito. Por cierto, parece lógico volver a calcular las reglas cuando los hechos cambian.