2012-05-23 18 views
2

我想写一个积累功能,需要知道当前时间。 我明显可以使用System.currentTimeMillis(),但是为了测试即时通讯和伪时钟运行drools会话,并希望能够测试这个函数。访问流水线会话时钟从累加功能或规则代码

即时通讯寻找一种获得会话时钟(或更好的是,KnowledgeRuntime)的方法,无论是从getResult()方法,还是如果不可能,从drools代码本身(在部分时)我可以将时钟传递给函数

回答

4

使用时钟时要小心,因为您可能会有不少惊喜。请注意,当将事实/事件插入会话或使用更新/修改调用进行修改时,将评估约束条件。这意味着约束被评估时的时间可能与规则被触发时的时间不同。这就是为什么Drools不会将当前时间直接暴露给LHS模式的原因。

话虽如此,要做到这一点的方法是插入会话时钟作为事实到会话中,并将其绑定任何其他事实:

rule X 
when 
    $clock : SessionClock() 
    ... your patterns/accumulate/etc ... 
then 
    ... 
end 
+0

ok,但SessionClock即时插入不会是一个静态副本 - 它将是一个活的对象引用,对吧?这意味着从它得到时间会给我“正确的”时间(功能评估的会话时间,而不是事件插入)。 ,并且,鉴于我的会话是持久化和序列化的 - 会话时钟是否可以快速序列化?如果没有,我如何设置它,以便我可以避免序列化并在会话激活时重新提供它? – radai

+0

如果您插入会话时钟作为事实,则每次提前时钟时,都需要调用update()来通知引擎。也许你可以与时钟分享你想要做的事情,也就是说,为什么你的累积功能需要它,并且我们可以以这种方式更好地帮助你。 –

+0

这个想法是这样的 - 可以说我有一个硬盘驱动器(C :),我每天都会抽样。每个样本只有两块数据 - 空闲空间和时间戳。如果我的硬盘即将在一周内填满,我希望有规则可以解雇。为此,我需要编写一个累积函数,对最新的N个样本(长度窗口)执行线性回归,绘制趋势线,计算趋势线何时达到0(==自由空间不足)并检查此时间点比“now”少一周。这个“现在”参考是我需要时钟的地方。 – radai

1

在单元测试中,我发现,添加$clock : SessionClock()when会导致单元测试不触发,FWR(可能是因为我嘲笑它为SessionPseudoClock,因此在工作记忆中没有SessionClock事实)。

我能够然而获得会话时钟(伪或实数),而无需一个条件绑定,通过使用droolsKnowledgeHelper实例:

例如

then 
    System.out.println(String.format(
     "It is now %s", 
     new java.util.Date(drools.getWorkingMemory() 
            .getSessionClock() 
            .getCurrentTime()) 
     .toString()));