我无法理解JBoss Drools推理引擎如何与复杂的事件处理(drools融合)协同工作。实际上我创建了一个规则,以便在不到5秒的时间内发生超过2次交易时拒绝交易。这是规则
rule "more than 2 transaction in 5 seconds"
when
$transaction : Transaction( $id : id )
Number(intValue > 2) from accumulate(
$t : Transaction() over window:time(5s),
count($t))
then
$transaction.setDenied(true);
end
我使用伪会话时钟以流模式设置会话。 这里是java代码
SessionPseudoClock clock = kSession.getSessionClock();
Transaction tx1 = new Transaction(new BigInteger("10000"), TransactionType.CREDIT_CARD, 1L);
Transaction tx2 = new Transaction(new BigInteger("2000"), TransactionType.CREDIT_CARD,2L);
Transaction tx3 = new Transaction(new BigInteger("50000"), TransactionType.DEPOSIT,3L);
Transaction tx4 = new Transaction(new BigInteger("100"), TransactionType.WITHDRAW,4L);
assertTransaction(kSession, tx1);
clock.advanceTime(6, TimeUnit.SECONDS);
assertTransaction(kSession, tx2);
clock.advanceTime(3, TimeUnit.SECONDS);
assertTransaction(kSession, tx3);
clock.advanceTime(1800, TimeUnit.MILLISECONDS);
assertTransaction(kSession, tx4);
其中assertTransaction simple包含以下代码:
kSession.insert(tx);
kSession.fireAllRules();
触发规则匹配的事务是tx4,因为tx2发生在tx1和tx1超出定时窗口后6秒。奇怪的是,即使对于tx1,也会对工作内存中的所有事务执行规则的操作。
它应该以这种方式工作吗?
提前致谢
答案 0 :(得分:0)
主要问题是引擎没有机会执行待处理的激活并根据(伪)时钟的当前读数处理事实。此外,该规则将针对当前处于工作内存中的每个事务触发,而您希望它仅针对最新事务触发。
通过CEP,测试或生产,我建议在一个单独的线程中运行Engine,调用fireUntilHalt。然后,为了测试或生产,可以使用真实时钟并在它们来时插入事实,或者从插入之间暂停的线程中插入事实。并且也可以使用伪时钟,几乎不需要对代码进行任何更改。
要确保规则仅针对最近的线程触发,请将规则更改为
rule "more than 2 transaction in 5 seconds"
when
$transaction : Transaction( $id : id )
not Transaction( this after $transaction )
Number(intValue > 2) from accumulate(
$t : Transaction() over window:time(5s),
count($t))
then
System.out.println( "denied: " + $transaction );
end