首页 > 解决方案 > 事实组的不同伪时钟

问题描述

我是 drools / fusion (7.x) 的新手,不知道如何解决这个要求。假设我的事件对象为 Event{long: timestamp, id: string},其中 id 标识物理资产(如拖拉机),timestamp 表示事件相对于资产触发的时间。在我的场景中,这些事件不会“实时”到达我的系统,这意味着它们可能会延迟几秒钟、几分钟甚至几天。我的规则系统需要监控多个资产。鉴于此,当评估规则时,时钟需要与被监控的资产相关,它不能是跨越资产的时钟。我知道伪时钟,有没有办法为每个资产分配伪时钟?

我的假设是时钟必须始终向前推进,否则时间功能将无法正常工作。以以下场景为例:资产 1 的事实 A 在 1:00 到达,它被插入内存并触发规则。然后事实 B 在 2:00 到达相同的资产 1。它也被插入并触发了规则。现在 Fact Z 在 1:30(距时钟 30 分钟)到达资产 2。我假设我不应该简单地将时钟倒退并评估,此外,我想将时钟设置回 2:00,因为那是我收到的“最新”数据。现在假设我正在监控数以千计的资产,所有资产都在不同的时间发送数据......

我认为解决此问题的最佳方法是为每个资产保留一个时钟,然后在评估每个资产数据时保存引擎状态。单个 KieSession 可以有不同的时钟,还是在容器级别?

示例规则:当同一资产的事实 1 在事实 2 之后到达时。

标签: droolsdrools-fusion

解决方案


您正在错误地解决问题。无论您使用的是实时时钟还是伪时钟,您都在使用时钟。你不能说“事实 #1 使用时钟 A,而事实 #2 使用时钟 B”。

相反,您应该利用事件的元数据标签,特别是@timestamp标签。这个标签向 Drools 表明事件内部的特定字段实际上是事件的时间戳,而不是事实进入工作内存的实际时间。

例如:

import com.example.SampleEvent

declare SampleEvent
  @role( event )
  // this field is actually in the object, it's not the time the fact was inserted
  @timestamp( createdDateTime ) 
end

不知道您的规则实际上在做什么,我可以预见的主要问题是,如果您的规则依赖于时间运算符或定义到期(@expires),它们将不起作用,您需要重新设计它们. 特别是对于过期:一旦事件过期,它就会从工作内存中删除;当您的带外事件进入时,任何以前过期的事件都已经消失并且无法处理。

当然,无论您是否使用@timestamp或您原来的“不同的伪时钟”计划,这种担忧都是真实的。无论哪种方式,您都将不得不处理事件不能永远存在于工作内存中的事实——您最终将耗尽资源并且您的系统将崩溃。事件必须在某个时候被驱逐,因此您需要在模型和规则中围绕它进行设计。


推荐阅读