【发布时间】:2018-11-08 17:58:00
【问题描述】:
我们正在开发一个资源预订系统,我们将在该系统中接收任意时间(从 5 分钟到 2 小时不等)预订资源的请求。没有预定义的插槽。
我们尝试使用 Drools (Fusion) 版本。 7.12.0.Final,编写规则以确保新的预订请求不会覆盖已确认的现有请求。
为了实现上述目的,我们创建了以下 2 个对象:
declare ReservationRequest
@role ( event )
@duration (reservationDuration )
@timestamp ( pickupTime )
id : int
pickupTime : Date
reservationDuration : long
reserved : String
deliveryEnd : Date
end
和
declare Reservation
reservation : ReservationRequest
end
“ReservationRequest”被视为事件,因此我们可以使用时间运算符来评估新请求不会与已确认的请求重叠(捕获为推断的“Reservation”事实。
我们编写了以下规则来检查重叠并插入相应的“预订”事实:
rule "Ensure no overlaped reservations using inferred facts"
enabled true
when
reservationRequest : ReservationRequest( )
not Reservation ( reservation == reservationRequest )
reservations : Reservation()
not ReservationRequest( this overlaps reservations.reservation )
not ReservationRequest( this overlappedby reservations.reservation )
not ReservationRequest( this includes reservations.reservation )
then
insert( new Reservation ( reservationRequest ) );
end
很遗憾,如果 WM 中存在“预订”事实,上述规则将无法运行。我收到以下错误:
java.lang.RuntimeException: Conversion to long not supported from com.sample.ReservationRequest
at org.drools.core.base.extractors.BaseObjectClassFieldReader.getLongValue(BaseObjectClassFieldReader.java:133)
at org.drools.core.base.ClassFieldReader.getLongValue(ClassFieldReader.java:198)
at org.drools.core.rule.VariableRestriction$TemporalVariableContextEntry.updateFromTuple(VariableRestriction.java:641)
at org.drools.core.common.SingleBetaConstraints.updateFromTuple(SingleBetaConstraints.java:116)
at org.drools.core.phreak.PhreakNotNode.doLeftInserts(PhreakNotNode.java:108)
at org.drools.core.phreak.PhreakNotNode.doNode(PhreakNotNode.java:85)
at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:571)
at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:552)
at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:379)
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:339)
at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:175)
at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:133)
at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:212)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:87)
at org.drools.core.concurrent.AbstractRuleEvaluator.internalEvaluateAndFire(AbstractRuleEvaluator.java:34)
at org.drools.core.concurrent.SequentialRuleEvaluator.evaluateAndFire(SequentialRuleEvaluator.java:43)
at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1067)
at org.drools.core.common.DefaultAgenda.internalFireAllRules(DefaultAgenda.java:1014)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1006)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1337)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1328)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1312)
at com.sample.DroolsTest.main(DroolsTest.java:24)
我们在其他场景中广泛使用了推断事实,但这是我们第一次将它用于事件。所以我们不确定是否支持这种能力(根据相关事件推断事实)。
如果这不受支持,那么在允许从 WM 中逐出/收回其他事件的同时“保存”所需事件的最佳方法是什么。我们可以使用“标志”来标记我们想要保留的事件,但我们希望尽可能避免这种方法。
谢谢
【问题讨论】: