Drools事件生命周期

Drools事件生命周期,drools,drools-fusion,Drools,Drools Fusion,我必须制定一对规则来撤销我的事件。它们似乎没有过期。我想要一个,并且做了很多事情。你可以在下面看到,他们使用默认的持续时间,零 例如,如果我排除了收回规则,然后先插入RemoveConnectionEvent,然后插入CreateConnectionEvent,RemoveConnection规则仍然会触发。(在我的单元测试中使用日程表侦听器) 我对事件的期望是RemoveConnectionEvent将被忽略,如果不立即满足其条件,它将不会做任何事情。我没想到当NewConnection规则响

我必须制定一对规则来撤销我的事件。它们似乎没有过期。我想要一个,并且做了很多事情。你可以在下面看到,他们使用默认的持续时间,零

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

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

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

有什么想法吗

ps这是一个很好的问答,但我不使用windows。这可能会推断出我的攻击可能是一个“显式过期策略”

这是我的规则

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

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

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

也许您有一个用于事件的公共(抽象)基类;否则,创建一个标记接口并将其附加到所有事件。我们将此类型称为
事件
。那么,只有一条规则

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 );

创建基址时。我还建议“让时间过去”,即提前一个伪时钟,或让线程在插入事实后的一两个瞬间运行一个
fireUntilHalt

添加了明确的过期设置作为替代。您好,我是您链接的Q&a滑动窗口的op。我认为@laune下面的回答和往常一样非常完整,仅供参考,因为您在代码中没有提到如何管理会话时钟,这个与滑动窗口无关,但与会话时钟同步和自动事件过期相关的另一个复制器可能与您的用例类似。希望这也有帮助,再见