我是Drools的新手。我想在解雇规则后延迟5秒(并且只是一次)。所以,我使用timer(int:5s)来做到这一点。但我发现在执行规则后,我的控制台应用程序将永远不会被终止,并且我的任务管理器中仍然存在其javaw.exe进程。唯一的方法是调用ksession.dispose()。但这是不可接受的,因为在我们的集群架构师中很难找到这种关系。
那么,在执行规则后,有没有办法让ksession自动处理?
以下是我的简单测试用例:
主要课程
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");
}
}
drl file
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,因为timer(int:5s)不是间隔计时器。
答案 0 :(得分: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
提示:否定条件X 不 not X
!
答案 1 :(得分:0)
基于laune的好答案,我修改了我的drl文件以确保drools.halt()始终会被命中。 (注意:v6.4.0 Final是可以的。但是v5.6.0 Final会为do子句抛出异常)
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();
端