Ciao,我已经通过多种方式进行了测试,但我仍然无法测试和验证 Drools Fusion 中的事件过期机制,所以我正在寻找一些小指导,好吗?
我已阅读手册并且对此功能感兴趣:
In other words, one an event is inserted into the working memory, it is possible for the engine to find out when an event can no longer match other facts and automatically retract it, releasing its associated resources.
我在 Eclipse 5.4.0.Final 中使用 Drools IDE,并修改了“新建 Drools 项目”向导创建的模板代码来测试和验证事件过期。
下面的代码。我理解的让“生命周期”正常工作的方法是:
- 您必须在 STREAM 模式下设置 KBase - 检查
- 您必须按时间顺序插入事件 - 检查
- 您必须定义事件之间的时间约束 - 在我的情况下检查是最后一个 Message()
但是,当我最后检查 EventFactHandle 时,没有任何 Event() 已过期。 感谢您的帮助。
Java:
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;
}
}
}
流口水:
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)
我仍然没有得到预期的结果,即插入的第一个消息事件,我本来预期现在已过期?感谢您的帮助。
最佳答案
找到解决办法了!显然,我很愚蠢,没有意识到我正在使用 Drools 5.4.0.Final,同时仍然引用 5.2.0.Final 的旧文档。在 Drools Fusion 5.4.0.Final 的更新文档中,为 2.6.2 添加了此框。滑动长度窗口:
Please note that length based windows do not define temporal constraints for event expiration from the session, and the engine will not consider them. If events have no other rules defining temporal constraints and no explicit expiration policy, the engine will keep them in the session indefinitely.
因此,我最初提出的第三个要求“您必须定义事件之间的时间约束”显然没有得到满足,因为我现在了解了 Drools 5.4.0.Final 中的滑动长度窗口:
Message() over window:length(1)
确实不是 session 中事件到期的时间约束的定义。
更新此答案希望有人会发现它有帮助。另外,正如您所知,我实际上很愚蠢,因为依靠谷歌搜索才能找到文档,有时您不会被重定向到当前的发行文档,所以看起来...
关于drools - Drools Fusion CEP 中的测试事件到期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12338385/