2016-10-30 2 views
0

Я новичок в Drools. Я хочу отложить 5 секунд после того, как я уволил правило (и только один раз). Итак, я использую timer (int: 5s) для этого. Но я обнаружил, что после выполнения правила консольное приложение никогда не будет прекращено, и его процесс javaw.exe все еще существует в моем диспетчере задач. Единственный способ - вызвать ksession.dispose(). Но это неприемлемо, потому что трудно найти этот ksession в нашем кластерном архитекторе.Сценарий правила таймера, основанного на тайм-аутах, всегда находится в памяти и вызывает утечку памяти

Итак, есть ли способ сделать ksession автоматически удаленным после выполнения правила?

Вот мой простой тест:

  1. главный класс

    public class App { 
        public static void main(String[] args) { 
         System.out.println("Started...");  
    
         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
         kbuilder.add(new ClassPathResource("Timer.drl", App.class), ResourceType.DRL); 
         KnowledgeBase kbase = kbuilder.newKnowledgeBase(); 
         StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();   
         ksession.fireAllRules();   
    
         System.out.println("Ended"); 
        } 
    } 
    
  2. DRL файл

    package myDrools.TimerTest1 
    
    rule "Your First Rule" 
    
    timer(int:5s) 
    
    when 
        eval(true) 
    then 
        System.out.println("Finished"); 
    end 
    

    Выход будет:

    Started... 
    Ended 
    Finished 
    

Но мое консольное приложение никогда не будет прекращено. Здесь что-то не так? Я тестировал его как в Drools 5.6.0 Final, так и в 6.4.0 Final. Тем не менее, у обоих из них есть одна и та же проблема. Я думаю, что ksession должен быть удален, поскольку таймер (int: 5s) не является интервальным таймером.

ответ

0

Таймеры запускаются параллельно нити, проводящей сеанс, и сохраняют сеанс. В некотором смысле, они предназначены для использования в сеансах, работающих неопределенно, т. Е. Не запускать fireAllRules.

Следующий сценарий должен дать вам чистую остановку:

rule "Your First Rule" 
    timer(int:5s) 
when 
then 
    System.out.println("Finished"); 
    drools.halt(); 
end 

И ваша сессия начинается так:

kieSession.fireUntilHalt(); 
System.out.println("return from fireUntilHalt"); 
kieSession.dispose(); 

Редактировать

Если вам нужно вызвать остановку в в любом случае вы можете добавить другое правило с отрицательным условием, которое сразу же приостанавливает.

rule "stop if not met" 
when 
    // negated condition X 
then 
    drools.halt(); 
end 

Подсказка: инвертированное условие Х неnot X!

+0

Привет Laune, Спасибо вам за ответ. Для этого решения существует проблема. Если когда часть не соответствует действительности, drools.halt() не пострадает. Итак, есть ли что-то вроде finally, чтобы убедиться, что drools.halt() можно запустить? – capcom923

+0

У меня есть не очень хорошее решение, которое нужно использовать do [abc], затем ...то [abc] – capcom923

+0

Возможно, безусловное правило с таймером (int: 6s) (6 = 5 + 1) будет самым простым решением :-) – laune

0

Основываясь на замечательном ответе Луэны, я изменил свой файл drl, чтобы убедиться, что drools.halt() всегда будет ударяться. (Примечание: v6.4.0 Final ОК Но v5.6.0 Final выбросит исключение для пункта делать.)

dialect "mvel" 
rule "Hello World" 
timer(int:5s) 
when 
    m : Message() 
    if (m.status == Message.HELLO) 
    do[hello] 
then 
    System.out.println("other status"); 
    drools.halt(); 
then[hello] 
    System.out.println("Hello!"); 
    drools.halt(); 

конец