Drools 中@duration 和@expires 的区别

Difference between @duration and @expires in Drools

我不完全理解 Drools 中事件的 @duration@expires 元数据标签之间的区别。有人可以澄清一下吗?

事件的持续时间 是事件持续的时间。它的过期是从工作内存中删除的时间。

想到这一点的最简单方法是将它们与 real-world 概念联系起来。现实世界的“事件”(例如,会议)有一定的持续时间(例如 1 小时)。它的到期时间是它“从”您的日历上“消失”的时间。如果您正在为您的日历建模,会议事件的到期将是我们不再关心它的时间点,可能是在一天或工作周结束之后。

这种区别的原因是因为 temporal operators 允许我们根据同时发生的事件编写条件规则。由于事件不是瞬时的(例如,当您不使用 point-in-time 事件时,它们有一个 duration),它们可以以多种方式重叠。一旦事件过期,它就会从工作内存中删除,后续事件和规则执行将不再考虑该过期事件。


这是一个例子。假设我们正在构建一个应用程序,用户可以尝试 3 次输入密码。每次尝试失败后,有 3 分钟的冷却时间,然后他们才可以再次尝试。如果用户在 30 分钟内有 3 次登录尝试失败,他们将被锁定;在这 30 分钟结束后,我们不再关心该事件并可以丢弃它。

对于这个用例,我们将事件命名为 AccessDisallowed。它有 3 分钟的持续时间,因为那是它“活跃”的时间量。它的有效期为 30 分钟,因为 lock-out 仅在 window.

的 30 分钟内触发
declare AccessDisallowed
  @duration( cooldownTime ) // property holding the duration, 3 minutes
  @expires( 30m )
end

然后我们可以编写规则来利用这些事件的持续时间和到期时间。在这些示例规则中,我只是要打印消息;在真实系统中,副作用可能包括警告安全系统,或锁定数据库中的用户记录。

rule "Disallow access for 3 minutes after Access Disabled"
when
  $lockoutPd: AccessDisallowed()
  PasscodeEntry( this during $lockoutPd )
then
  System.out.println("Passcode entry detected during lockout period.");
end

rule "Lock account after 3 Access Disables"
when
  List( size >= 3 ) from accumulate( $a: AccessDisallowed(), collectList($a) )
then
  System.out.println("3+ login attempts within 30m detected");
end

第一条规则很简单。当收到 PasscodeEntry 事件时,我们会检查当前是否有正在进行的 AccessDisallowed 事件。如果有,我们会做出相应的回应。这利用了 duration.

第二条规则利用了过期。如果 30 分钟内有 3 次登录尝试 window,我们将锁定该帐户。在本例中,我们利用了 30 分钟后 AccessDisallowed 事件过期并从工作内存中删除的事实;因此,如果曾经有 3 个 AccessDisallowed 事件 工作内存中,那么按理说它们都是在过去 30 分钟内放在那里的。

(在 real-world 应用程序中,我们可能会使用滑动 windows 或带有累加器的时间 after 运算符来检测最后一个条件,因为我们可能需要做其他工作关于实际发生的事件。)