доступ к часам сеанса drools из функции накопления или кода правила

Я пытаюсь написать функцию накопления, которая должна знать текущее время. Я, очевидно, мог бы использовать System.currentTimeMillis(), но для тестирования я запускаю сеанс drools с псевдо-часами и хотел бы иметь возможность протестировать эту функцию.

я ищу способ получить часы сеанса (или, что еще лучше, KnowledgeRuntime) либо из метода getResult(), либо, если это невозможно, из самого кода drools (в разделе когда), чтобы я мог передать часы на функцию


person radai    schedule 23.05.2012    source источник


Ответы (2)


Будьте осторожны при работе с часами, так как у вас может быть немало сюрпризов. Обратите внимание, что ограничения оцениваются, когда факты/события вставляются в сеанс или изменяются с помощью вызова update/modify. Это означает, что время по часам при оценке ограничения, вероятно, будет отличаться от времени по часам при срабатывании правила. Именно по этой причине drools не отображает текущее время непосредственно в шаблонах LHS.

Сказав это, способ сделать это - вставить часы сеанса как факт в сеанс и связать их как любой другой факт:

rule X
when
    $clock : SessionClock()
    ... your patterns / accumulate / etc  ...
then
    ...
end
person Edson Tirelli    schedule 23.05.2012
comment
хорошо, но SessionClock, который я вставляю, не будет статической копией - это будет ссылка на живой объект, верно? это будет означать, что получение времени от него даст мне правильное время (время сеанса при оценке функции, а не вставка события). и, учитывая, что мои сеансы являются постоянными и сериализованными, можно ли быстро сериализовать часы сеанса? если нет, как мне его настроить, чтобы я мог избежать его сериализации и повторно предоставить его при активации сеанса? - person radai; 24.05.2012
comment
Если вы вставляете часы сеанса как факт, каждый раз, когда время часов увеличивается, вам нужно вызывать update(), чтобы уведомить движок. Может быть, вы можете поделиться тем, что именно вы хотите сделать с часами, т. е. зачем они нужны вашей функции накопления, и мы сможем помочь вам лучше. - person Edson Tirelli; 24.05.2012
comment
идея такова - скажем, у меня есть жесткий диск (c:), который я пробую каждый день. каждый образец имеет только две части данных - свободное пространство и отметку времени. я хочу, чтобы правило срабатывало, если мой жесткий диск вот-вот заполнится менее чем за неделю. для этого мне нужно написать функцию накопления, которая выполняет линейную регрессию для последних N выборок (окно длины), строит линию тренда, вычисляет, когда линия тренда достигает 0 (== вне свободного места) и проверяет, является ли этот момент времени меньше чем через неделю. это теперь ссылка, где мне нужны часы. - person radai; 24.05.2012
comment
В вашем случае использования время — это определенно факт, над которым вы должны рассуждать, поэтому я рекомендую вам вставить часы сеанса как факт. Кроме того, я не уверен, что самой функции накопления нужно знать текущее время... мне кажется, что ей нужно знать только время событий, которые она использует для линейной регрессии. Результатом будет дата, когда линия тренда достигнет 0 относительно имеющихся у вас выборок. Наконец, отдельное правило может использовать результат вычислений для срабатывания сигнализации, если это произойдет менее чем через неделю с использованием часов. - person Edson Tirelli; 24.05.2012
comment
Сериализация должна нормально работать с часами, но я никогда не проверял ее сам. - person Edson Tirelli; 24.05.2012
comment
если я вставлю часы сеанса как факт и использую его getCurrentTime() в DRL, это сработает? не будут ли слюни кэшировать возвращаемое значение getCurrentTime()? Кроме того, поскольку все эти правила будут генерироваться автоматически, я бы предпочел сохранить всю функциональность в одном правиле, а не распределять его по нескольким, для удобства управления. - person radai; 24.05.2012

Во время модульного тестирования я обнаружил, что добавление $clock : SessionClock() к when приведет к тому, что модульные тесты не будут запускаться, FWR (вероятно, потому, что я смоделировал его как SessionPseudoClock и, следовательно, в рабочей памяти не было фактов SessionClock).

Однако мне удалось получить часы сеанса (псевдо или реальные) без условной привязки, используя экземпляр drools KnowledgeHelper:

e.g.

then
  System.out.println(String.format(
      "It is now %s", 
         new java.util.Date(drools.getWorkingMemory()
                                  .getSessionClock()
                                  .getCurrentTime())
         .toString()));
person StuartLC    schedule 22.11.2013