Drools事件生命周期

时间:2015-12-01 17:23:09

标签: drools drools-fusion

我必须创建一对规则来收回我的活动。它们似乎没有过期。我曾经想过一次又一次的活动。您可以在下面看到,它们使用默认持续时间,零。

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

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

为了使我的规则符合我的预期,我创建了RetractedCreation,RetractedRemoval和RetractedUpdate。这似乎是一个黑客。我想象我的事件被宣布错了。

有什么想法吗?

ps这是一个非常好的Q& A,但我没有使用Windows。它可能会推断,或许我的黑客是一个明确的过期政策'。

Test Event expiration in Drools Fusion CEP Test 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

1 个答案:

答案 0 :(得分:1)

这种自动过期是一个相当难以捉摸的特征。当它工作时没有简明的定义,以及需要做些什么才能使它发挥作用。

在你显然很简单的情况下,你不使用时间运算符,并期望事件在匹配一个规则后收回,我采用以下策略而不会浪费另一个思想。推断到期"和#34;托管生命周期"。

也许你的事件有一个共同的(抽象的)基类;否则创建一个标记界面并将其附加到所有事件。我们称这种类型为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以实现jiffy或两次事后插入。