【问题标题】:Error with pseudo clock in drools when I have two rules matching different events当我有两个匹配不同事件的规则时,drools 中的伪时钟出错
【发布时间】:2016-02-07 15:13:01
【问题描述】:

我想用场景测试drools 6.3,但是在特殊情况下我遇到了问题。 这是我的一个简单形式的场景: 我在生成事件的模拟网络中有两个系统,A 和 B。我想写两条规则来找出这些事件中的模式。测试此场景的两条规则是:

declare A
  @timestamp(timestampA)
end

declare B
  @timestamp(timestampB)
end

Rule “1”
When
    accumulate( A() over window:time( 10s ) ; s:count(1) ; s>1)
Then
    System.out.println( " Rule 1 matched " );

Rule “2”
When
    B()
Then
    System.out.println( " Rule 2 matched " );

每个事件的时间戳是每个系统中生成的日志的时间戳,当它被 drools 接收并插入工作内存时。 我正在使用带有伪时钟的 STREAM 模式,因为来自系统 B 的事件由于网络拥塞而延迟 25 分钟接收,我应该手动调整会话时钟。会话时钟设置为插入到会话中的每个事件的时间戳。并且在插入每个事件时都会触发所有规则。 当接收和插入事件的顺序如下正确匹配时。

Event A received at 10:31:21 – Session clock : 10:31:21 – insert A and fire
Event A received at 10:31:23 - Session clock : 10:31:23 – insert A and fire
Rule 1 matched
Event B received at 10:06:41 - Session clock : 10:06:41 – insert B and fire
Rule 2 matched

但是当接收和插入事件的顺序如下所示时匹配不正确:

Event A received at 10:31:21 – Session clock : 10:31:21 – insert A and fire
Event B received at 10:06:41 - Session clock : 10:06:41 – insert B and fire
Rule 2 matched
Event A received at 10:31:23 - Session clock : 10:31:23 – insert A and fire

当第二个 A 事件插入时,最后 10 秒的两个 A 事件在工作内存中,但规则 1 不匹配。为什么?

【问题讨论】:

    标签: drools


    【解决方案1】:

    您所做的与 Drools 的 CEP(连续事件处理)的假设有些冲突。 STREAM 模式意味着事件应该按照它们的时间戳顺序插入,而不管它们的来源。在大跳跃中来回设置伪时钟是另一种混淆引擎的好方法。

    不要使用 STREAM 模式、window:time 并忘记会话时钟。

    您有包含时间戳的事实,您可以通过引用这些时间戳轻松编写规则,或者使用简单的旧算术或应用时间运算符(它们只不过是用于测试 long 关系的语法糖(如在 java.lang) 值。

    【讨论】:

    • 另一种选择(尽管可能与其他要求相冲突)可能是使用伪时钟并根据接收到的事件时间戳手动推进它。对于这种情况,我参考了 Drools 的 twitter CBR 示例 github.com/droolsjbpm/droolsjbpm-contributed-experiments/blob/…。然后通过缓冲和/或丢弃来缓解延迟 - 此缓解策略确实可能与其他要求发生冲突,因此使此选项不适用于全局。
    • @tarilabs 但是手动调整伪时钟正是 OP 正在做的事情 - 它不适用于来回时间戳
    • 准确地说,我指的是 Drools 的伪时钟。 (Drools') 伪时钟只能提前,如果我看到问题中的日志看起来 OP 正在倒带会话的时钟,因此我怀疑 OP 正在使用伪时钟,并且我认为 OP 正在使用违反 CEP 合同的自定义时钟实现.使用伪时钟(API 只能提前)将确保满足 CEP 要求,然后将问题“推迟”到在推进伪时钟和插入(或丢弃)事件时使用的缓冲和/或丢弃策略。跨度>
    • @tarilabs 方法被称为“advanceTime”这一事实并不意味着您不能用负值调用它。那么,为什么说伪时钟只能进阶呢?
    • Touché - 在这些用例场景中,我总是在伪时钟“advanceTime”方法调用上游实现缓冲和/或丢弃策略,我想我从未注意到伪时钟 API 实际上可能是“弯曲的”这边走。感谢您指出这一点@laune!
    猜你喜欢
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多