我不得不创建成对的规则来收回我的事件。它们似乎不会过期。我想要一个,并做了一些活动。你可以在下面看到,他们使用默认的持续时间,零。
因此,例如,如果我排除撤回规则,然后先插入RemoveConnectionEvent,然后插入CreateConnectionEvent,那么RemoveConnection规则仍然会触发。(在我的单元测试中使用议程监听器)
我对事件的期望是RemoveConnectionEvent将被忽略,如果不立即满足其条件,它将不会执行任何操作。我没想到当NewConnection规则响应CreateConnectionEvent时,一旦满足规则条件,它就会挂起并触发RemoveConnection规则。
为了让我的规则按预期运行,我创建了RetractedCreation、RetractedRemoval和RetractedUpdate。这似乎是一次黑客攻击。我在想象一个宣布我的事件是错误的。
有什么想法吗?
ps这是一个非常好的问答;A但我不使用窗户。它可能会推断,也许我的破解是一个"明确的过期策略"。
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
此自动到期功能相当难以捉摸。它什么时候能起作用,以及需要做些什么才能起作用,目前还没有一个简明的定义。
在你明显简单的情况下,如果你不使用时态运算符,并期望事件在匹配一条规则后被撤回,我会采取以下策略,而不会在"推断到期"one_answers"管理生命周期"上浪费另一个想法。
也许您的事件有一个通用(抽象)基类;否则,创建一个标记接口并将其附加到所有事件。让我们把这种类型称为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
。