Drools 流口水时@duration和@expires之间的差异

Drools 流口水时@duration和@expires之间的差异,drools,Drools,我不完全理解Drools中事件的@duration和@expires元数据标记之间的区别。有人能澄清这一点吗?事件的持续时间是指事件持续的时间。它的到期时间是从工作内存中删除时 考虑这一点最简单的方法是将它们与现实世界的概念联系起来。现实世界中的“事件”(例如,会议)有一定的持续时间(例如1小时)。它的过期时间是它“从”你的日历上“消失”的时间。如果您正在为日历建模,那么会议事件的到期时间将是我们不再关心它的时间点,可能是在当天或工作周结束之后 这种区别的原因是,允许我们根据同时发生的事件为条件

我不完全理解Drools中事件的
@duration
@expires
元数据标记之间的区别。有人能澄清这一点吗?

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

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

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


这里有一个例子。假设我们正在构建一个应用程序,其中用户有3次尝试输入密码。每次尝试失败后,有3分钟的冷却时间,然后才允许他们重试。如果用户在30分钟内有3次登录尝试失败,则会被锁定;在这30分钟结束后,我们不再关心比赛,可以放弃比赛

对于这个用例,我们将事件命名为
AccessDisallowed
。它的持续时间为3分钟,因为这是它“活动”的时间量。它的过期时间为30分钟,因为锁定仅在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事件。如果有,我们会作出相应的回应。这利用了持续时间

第二条规则利用到期时间。如果在30分钟内有3次登录尝试,我们将锁定帐户。在这种情况下,我们利用了30分钟后AccessDisallowed事件过期并从工作内存中删除的事实;因此,如果在工作记忆中有3个不允许访问的事件,那么它们都是在过去30分钟内出现的


(在现实世界的应用程序中,我们可能会使用滑动窗口或带有累加器的时态
after
操作符来检测最后一种情况,因为我们可能需要对所讨论的实际事件进行其他工作。)

expires标记可以接受变量吗?我从未尝试过。根据文件,它只取时间偏移量(如1m45s、30m、1h等)