Ciao,我已经通过多种方式进行了测试,但我还是无法测试和验证Drools Fusion中的事件到期机制,所以我想找一些小指导吗?
我已阅读本手册,我对此功能感兴趣:
换句话说,一个事件被插入到工作内存中,引擎可以找出事件何时不能与其他事实匹配并自动撤消它,释放其相关资源。
我在Eclipse中使用Drools IDE,5.4.0.Final,我修改了" New Drools Project"创建的模板代码。向导测试并验证事件到期。
以下代码。我理解的方式是做生命周期"正确地工作是:
但是,当我在最后检查EventFactHandle时,没有Event()过期。 谢谢你的帮助。
爪哇:
public class DroolsTest {
public static final void main(String[] args) {
try {
KnowledgeBase kbase = readKnowledgeBase();
// I do want the pseudo clock
KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
conf.setOption(ClockTypeOption.get("pseudo"));
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// Insert of 2 Event:
Message message = new Message();
message.setMessage("Message 1");
message.setStatus(Message.HELLO);
ksession.insert(message);
ksession.fireAllRules();
clock.advanceTime(1, TimeUnit.DAYS);
Message message2 = new Message();
message2.setMessage("Message 2");
message2.setStatus(Message.HELLO);
ksession.insert(message2);
ksession.fireAllRules();
clock.advanceTime(1, TimeUnit.DAYS);
ksession.fireAllRules();
// Now I do check what I have in the working memory and if EventFactHandle if it's expired or not:
for (FactHandle f : ksession.getFactHandles()) {
if (f instanceof EventFactHandle) {
System.out.println(((EventFactHandle)f)+" "+((EventFactHandle)f).isExpired());
} else {
System.out.println("not an Event: "+f);
}
}
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
// following 2 lines is the template code modified for STREAM configuration
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
return kbase;
}
/*
* This is OK from template, as from the doc:
* By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory.
*/
public static class Message {
public static final int HELLO = 0;
public static final int GOODBYE = 1;
private String message;
private int status;
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return this.status;
}
public void setStatus(int status) {
this.status = status;
}
}
}
Drools的:
package com.sample
import com.sample.DroolsTest.Message;
declare Message
@role(event)
end
declare window LastMessageWindow
Message() over window:length(1)
end
rule "Hello World"
when
accumulate( $m : Message(status==Message.HELLO) from window LastMessageWindow,
$messages : collectList( $m ) )
then
System.out.println( ((Message)$messages.get(0)).getMessage() );
end
请注意:即使我在消息事件中添加了1秒的到期时间,也可以通过
@expires(1s)
我仍然没有得到插入第一个Message事件的预期结果,我原以为现在已经过期了?谢谢你的帮助。
答案 0 :(得分:3)
找到解决方案!显然,这是我愚蠢而没有意识到我正在使用Drools 5.4.0.Final,同时仍然指的是5.2.0.Final的旧文档。在Drools Fusion 5.4.0.Final的更新文档中,此框添加了 2.6.2。滑动长度Windows :
请注意,基于长度的窗口不会为会话中的事件过期定义时间限制,引擎也不会考虑它们。如果事件没有定义时间约束的其他规则且没有明确的到期策略,则引擎将无限期地将它们保留在会话中。
因此,我最初申请的“你必须在事件之间定义时间约束”的第三个要求显然是不符合的,因为我现在理解Drools 5.4.0中的Sliding Length Window.Final:
Message() over window:length(1)
确实不是会话中事件过期的时间约束的定义。
更新此答案希望有人会觉得有帮助。另外,为了你的知道,我实际上依赖谷歌搜索以获得文档是愚蠢的,有时你不会被重定向到当前的发布文档,所以它似乎......