Drools 事件生命周期

Drools event lifecycle

我不得不创建成对的规则来撤消我的活动。看起来它们不会过期。我想要一劳永逸的活动。你可以在下面看到,他们使用默认持续时间,零。

因此,例如,如果我排除撤回规则,然后先插入 RemoveConnectionEvent,然后再插入 CreateConnectionEvent,则 RemoveConnection 规则仍会触发。 (在我的单元测试中使用议程监听器)

我对事件的期望是 RemoveConnectionEvent 会被忽略,如果不立即满足其条件,它不会做任何事情。当 NewConnection 规则响应 CreateConnectionEvent 时,一旦满足规则条件,我没想到它会徘徊并触发 RemoveConnection 规则。

为了让我的规则按预期运行,我创建了 RetractedCreation、RetractedRemoval 和 RetractedUpdate。这似乎是一个黑客。我在想象一个宣布我的事件是错误的。

有什么想法吗?

ps 这是一个很好的问答,但我没有使用 windows。它可能会推断出 perhaps 我的 hack 是 'explicit expiration policy'.

Test Event expiration in Drools Fusion CEPTest Event Expiration

这是我的规则。

package com.xxx
import com.xxx.ConnectedDevice
import com.xxx.RemoveConnectionEvent
import com.xxx.CreateConnectionEvent
import com.xxx.UpdateConnectionEvent

declare CreateConnectionEvent @role( event ) end
declare UpdateConnectionEvent @role( event ) end
declare RemoveConnectionEvent @role( event ) end

rule NewConnection
    when
        $connection : CreateConnectionEvent($newChannel : streamId)
        not ConnectedDevice( streamId == $newChannel )
    then
        insert( new ConnectedDevice($newChannel) );
end

rule RetractedCreation
    when
        $creationEvent : CreateConnectionEvent($newChannel : streamId)
        exists ConnectedDevice(streamId == $newChannel)
    then
        retract($creationEvent)
end

rule RemoveConnection
    when
        $remove : RemoveConnectionEvent($newChannel : streamId)
        $connection : ConnectedDevice( streamId == $newChannel )
    then
        retract( $connection );
end

rule RetractedRemoval
    when
        $removalEvent : RemoveConnectionEvent($newChannel : streamId)
        not ConnectedDevice(streamId == $newChannel)
    then
        retract($removalEvent)
end

rule UpdateConnection
    when
        $connectionUpdate : UpdateConnectionEvent($newChannel : streamId) 
        $connection : ConnectedDevice( streamId == $newChannel )
    then
    $connection.setLastMessage();
end

rule RetractedUpdate
    when
        $removalEvent : UpdateConnectionEvent($newChannel : streamId)
        not ConnectedDevice(streamId == $newChannel)
    then
        retract($removalEvent)
end

这种自动过期是一个相当难以捉摸的功能。没有简明的定义何时会起作用,以及需要做什么才能使其起作用。

在您不使用时间运算符并期望事件在匹配一条规则后被撤回的看似简单的情况下,我会采用以下策略,而不会在 "inferred expiration" 上浪费另一个想法,并且"managed lifecycle".

也许你们的活动有一个共同的(抽象的)基础 class;否则创建一个标记接口并将其附加到所有事件。我们称这种类型为 Event。然后,一条规则

rule "retract event"
salience -999999
when
    $e: Event()
then
    retract( $e );
end

将处理所有(创建、更新、删除)事件。

编辑您也可以使用事件过期的显式设置。

declare CreateConnectionEvent
    @role( event )
    @expires(0ms)
end

确保使用

KieBaseConfiguration config = ks.newKieBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
KieBase kieBase = kieContainer.newKieBase( config );

创建 KieBase 时。我还建议 "let the time pass",即提前一个伪时钟或让线程 运行 一个 fireUntilHalt 在事实插入后一两个瞬间。