drools - 事实组的不同伪时钟
问题描述
我是 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 之后到达时。
解决方案
您正在错误地解决问题。无论您使用的是实时时钟还是伪时钟,您都在使用时钟。你不能说“事实 #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
或您原来的“不同的伪时钟”计划,这种担忧都是真实的。无论哪种方式,您都将不得不处理事件不能永远存在于工作内存中的事实——您最终将耗尽资源并且您的系统将崩溃。事件必须在某个时候被驱逐,因此您需要在模型和规则中围绕它进行设计。
推荐阅读
- wcf - 在 IIS 上将客户端证书选项设置为“已接受”时未调用 CustomCertificateValidator
- .net - 无论如何要使用 dotnet CLI 启用解决方案级别的 SSL?
- powershell - 将 bool 参数传递给我的脚本总是会产生相同的输出
- javascript - 两个固定元素 z-index 问题
- python - 尝试使用 AWS s3.put_object 创建一个相同的空文件,由多个进程并行使用 python
- ios - 带有委托的 Swift 协议属性
- jsf - Web 过滤器中设置的 Cookie 在请求 bean 中不可用
- sql-server - 我们可以在 python 中对 SQL Server 执行基于 jdbc 的 AAD 身份验证吗
- knockout.js - 行为主体淘汰赛可观察到的表现
- javascript - 使用 React Hooks 获取先前的 props 值