如何在流口水中实现时间持久性?

问题描述

我是流口水的新手,我想知道是否有一种方法可以编写表达时间持久性的规则:

如果(条件为持续X秒),则执行doSomething()

Rule "Example"
when
  r: Room(Temperature > 100 for 10 minutes )
then
  doSomething()
end

解决方法

有两种触发Drools规则的模式-默认为“云”模式,在此模式下,我们可以在单个时间点评估工作内存中的所有事实。这是最古老,最常见的触发规则的方法。另一种模式是“流”模式,该模式连续播放数据,而Drools引擎则知道时间。

在流模式下,Drools具有一组temporal operators(链接到Drools文档),可用于针对随着时间而发生的事实编写条件。

可以将临时运算符用于用例的一种方法如下:

rule "Detect temperature over 100 for 10 minutes"
when
  $t: Temperature(this >= 100) from entry-point "TemperatureStream"
  not(
    Temperature(
      this != $t,this < 100,this after[0s,10m] $t) from entry-point "TemperatureStream")
then
  doSomething()
end

此简单规则希望您通过某种外部机制从入口点(TemperatureStream)发送温度事件。当它检测到温度超过100度(实例$t)时,将触发第一个条件。

第二个条件是魔术发生的地方。仅当第二个条件在收到$t后的10分钟内没有收到小于100度的温度事件时才触发。

当您的监视应用程序发送温度事件时,每100个以上的事件都会触发第一个条件,然后开始监视流以查看第二个条件是否成立。如果确实如此,则将触发规则的后果。否则,规则匹配项将被丢弃。

或者,您可以在10分钟内使用sliding window来查看最低温度是否降到100以下。

rule "Detect temperature over 100 for 10 minutes - sliding window"
when
  not(
    Number(doubleValue < 100) from accumulate(
      Room( $temperature: Temperature ) over window:time(10m),min( $temperature )
    )
  )
then
  doSomething()
end

在这里,window:time(10m)是10分钟内的滑动窗口。与另一种解决方案不同,该解决方案会先观察每个事件,然后尝试检查是否存在第二个条件,而该解决方案只是查看一段时间内的所有事件。如果整个窗口的最低温度从未低于100,则右侧触发。

可能还有其他方法可以做到,这只是我提出的两种方法。该文档对于Drools的这一部分特别有用,因此您可能会找到另一种更适合您的用例的方式。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...