Drools - 滑动窗口无法按预期工作

时间:2017-11-14 14:42:23

标签: drools

我是流口水的新手。我已经定义了以下规则来将流中的最后两个数字一起添加。然后我发送一个包含100个事件的流,其值设置为1到100.所以我希望输出为0,1,3,5,7,9,11,13等。

declare TestEvent
     @role( event )
     value : int
end
rule "Simple Rule"
when
    $sum : Integer() from accumulate ( TestEvent( $value : value ) over window:length( 2 ); sum( $value)  )
then
    System.out.println("Value: " + $sum );
end

会话在单独的线程中使用“fireUntilHalt”启动。如果我在插入的每个事件之间放置10毫秒的延迟,它会按预期工作。但是,当我没有延迟时,结果并不像预期的那样。通常它只打印0和197.有时我也可能会得到一两个中间数。

为什么会发生这种情况以及我应该采取哪些措施来解决这个问题?

3 个答案:

答案 0 :(得分:0)

滑动窗户是拐杖。用简单的逻辑代替它。

class Pred {
   Integer pred;
}

rule procInt1
when
  $p: Pred( pred == null )
  $i: Integer()
then
  modify( $p ){ setPred( $i ); }
end

rule procInt
when
  $p: Pred( $i1: pred != null )
  $i2: Integer()
then
  System.out.println( $i1 + $i2 );
  modify( $p ){ setPred( $i2 ); }
end

你有两个线程的事实并不意味着你不能有竞争条件。线程插入事件不会被暂停,因此一切皆有可能。

答案 1 :(得分:0)

好的,我终于明白了。 让fireUntilHalt在一个单独的线程中运行意味着只会不时地评估规则(不确定那个时间段是什么)。我的假设是每个insert都会对它们进行评估。因此,在每insert个累加器值都会更新,但评估的规则不会被评估。因为我的规则被快速插入(大约一秒钟),所以第一次和最后一次插入似乎都被评估了。

为了使这一点工作以便评估每个插入内容,我删除了fireUntilHalt,并在每次插入后单独执行了fireAllRules

答案 2 :(得分:0)

与时间相关的规则依赖于“时间”。流口水的最短时间间隔似乎是1毫秒。规则将在每次插入时进行评估(并将相应的后果添加到议程中),但是议程将在下一毫秒的滴答声中执行(或在您明确触发所有规则时执行)。