Слюни 7 - Рассуждение о событиях, связанных с предполагаемыми фактами - PullRequest
0 голосов
/ 08 ноября 2018

Мы работаем над системой резервирования ресурсов, где мы будем получать запросы на бронирование ресурса в любое произвольное время (от 5 минут до 2 часов). Там нет предопределенных слотов.

Мы пытаемся использовать Drools (Fusion) ver. 7.12.0. Наконец, написать правила, которые гарантируют, что новые запросы на бронирование не переопределят существующие запросы, которые были подтверждены.

Для достижения вышеизложенного мы создали следующие 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» обрабатывается как события, поэтому мы можем использовать временные операторы для оценки новых запросов, не перекрывая подтвержденные запросы (фиксируются как предполагаемый факт «Резервирования».

Мы написали следующее правило для проверки перекрытия и вставки соответствующего факта «Резервирование»:

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. Мы могли бы использовать «флаги», чтобы отметить события, которые мы хотим сохранить, но мы хотели бы избежать такого подхода, если это возможно.

Спасибо

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Я рекомендую добавить $ -sign перед именами переменных, тогда вы сможете лучше различать поля и переменные.

Если вы добавите метод boolean isOverlap(ReservationRequest) в класс ReservationRequest, вы можете написать что-то вроде этого:

when
    $reservationRequest : ReservationRequest( )
    not Reservation ( this.reservation.isOverlap($reservationRequest) )
then
    insert( new Reservation ( $reservationRequest ) );

Этого должно быть достаточно. Я также настоятельно рекомендую использовать имя переменной «bookingRequest», когда вы ссылаетесь на ReservationRequest, прямо сейчас это очень запутанно.

0 голосов
/ 09 ноября 2018

Я фанат Drools, почему бы вам просто не создать таблицу SQL с start_datetime и end_datetime вместе с триггером «before insert on», который проверяет, что вставленное значение не перекрывает ни одно из существующих (подтвержденных) значений в БД. Если триггер выдает исключение во время вставки, вы его ловите и знаете, что существует перекрытие.

...