流口水的时间限制和“现在”

时间:2016-01-02 07:56:34

标签: java date drools

我们正试图写一个流口水,上面写着“如果事件发生在上周,执行后果”。我们有常规的java日期对象来表示事件发生的时间,但我们不确定如何在LHS中表达我们希望在上周发生日期对象的流口水。重要的是,一周的时间跨度是任意的。它可以随时更改为月份或年份。最后,请记住我们的会话是有状态的。

我在这里找到了一个有点相关的问题: use java.util.Date in a rule's LHS。我将从下面的答案中引用最相关的摘录:

  

如果您在无状态会话中执行,那么您的方法   将与Fusion运营商合作。它仍然不是   但是,建议的做法。更好的方法是定义一个事实,   现在调用它,它包含一个Date字段。初始化并插入   它与你的其他事实一起然后反对它而不是一个   全球。

     

如果你有一个有状态的会话,它会变得更加棘手,因为   即使会话处于空闲状态,实时也在通过,这意味着你的现在   事实上越来越过时了。我们解决这个问题的方式   是通过使用WorkingMemoryEventListener。我们用的是   objectInserted,objectRetracted和objectUpdated方法   听众保持我们现在的事实是最新的(我们不关心精确度   不到一分钟,所以我们检查是否已经过了一分钟   最后更新,以避免不必要的开销)。规则不会评估是否   工作记忆不会改变,所以使用这个监听器就足够了   确保Now在需要时更新(除非你有   依赖于Now的当前值的查询,但那是另一个   主题)。

在答案中,作者描述了“现在”的表示问题。他的解决方案似乎很苛刻,答案是在早期版本的drools中发布的。我在这里提出一个新问题,以便更好地关注这个问题,而不是在我所链接的那个问题中得到的通过处理。

更新

时间戳是简单的java.util.Date对象。

通过api调用将事件添加到会话中。有状态会话是基于java的api持有的对象。 api在提交时将事件添加到知识会话中。 FireAllRules大约每秒发生一次。

1 个答案:

答案 0 :(得分:2)

基本问题(如此经常)是真正的含义。 “上周发生的”事件可能是7 * 24 * 60 * 60秒前发生的任何事情;它可能是从20151228周一到现在,或从20151227周日到现在发生的事情,或者类似于日期重要的事情,而不是当天的时间。

询问它的真正含义,并相应地重新解释你的问题。

如果你确实需要一个滑动窗口,从“现在”回来,即确实这一刻,在一段时间内( w 秒),你仍然需要定义速度和必须执行此检查的准确性。 Drools在绝对意义上没有持续更新“现在”的概念。可以创建和维护表示“现在”的近似的事实,使用计时器(优于使用监听器)。 Now-fact必须定期更新,每 d 秒。如果在上次更新“现在”之后插入带有时间戳的新事件,则最多 d 秒将无法识别。 (如果你过去在 w w + d 秒之间插入一个时间戳的新事件,它可能会触发规则。)

由于您尚未说明如何插入事件以及如何实施时间戳,因此我无法提供说明我所概述的内容的规则。请参阅Drools有关“计时器和日历”的文档。

修改

在问题中没有说过的是事件的时间(即,它真的发生在现实世界中)与其时间戳的关系(即,当它进入工作记忆时)。检查事件时间戳在过去一周或一个月或一秒内的规则是徒劳的:这将是无效的。

如果您反复调用fireAllRules,则在调用之前使用时间戳1周(月,...)更新时间范围是一种简单的方法。或者在每次通话前更新。两者都远非“hacky”。​​