0

我不得不创建成对的规则来撤回我的事件。好像没有过期。我想要一次性完成的活动。你可以在下面看到,他们使用默认的持续时间,零。

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

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

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

有任何想法吗?

ps 这是一个很好的问答,但我没有使用 Windows。它可能会推断出我的 hack 可能是一个“明确的过期策略”。

Drools Fusion CEP测试事件到期中的测试事件到期

这是我的规则。

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
4

1 回答 1

2

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

在您不使用时间运算符并期望事件在匹配一个规则后将被撤回的显然简单的情况下,我将采用以下策略,而不会在“推断到期”和“托管生命周期”上浪费另一种想法。

也许您的事件有一个通用(抽象)基类;否则创建一个标记界面并将其附加到所有事件。我们称这种类型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 时。我还建议“让时间过去”,即推进一个伪时钟或让线程fireUntilHalt在事实插入后运行一两秒。

于 2015-12-01T19:43:16.110 回答