Статьи

Исполняемая модель Drools жива

обзор

Цель исполняемой модели состоит в том, чтобы обеспечить чистое представление набора правил на основе Java вместе с удобным Java DSL для программного создания такой модели. Модель является низкоуровневой и предназначена для предоставления пользователю всей необходимой информации, например лямбда-индексов для оценки индекса. Это поддерживает скорость и позволяет избежать слишком большого числа допущений на этом уровне. Ожидается, что в будущем могут появиться представления более высокого уровня, которые могут быть более ориентированы на конечного пользователя. Эта работа также очень хорошо дополняет работу модуля, которая обеспечивает java-ориентированный способ предоставления данных и управления оркестровкой.

подробности

Эта модель достаточно универсальна, чтобы быть независимой от Drools, но может быть скомпилирована в простую базу знаний Drools. По этой причине реализация исполняемой модели была разбита на 2 подпроекта:

  1. drools-canonical-model — это каноническое представление модели набора правил, которая полностью независима от Drools
  2. drools-model-compiler компилирует каноническую модель во внутренние структуры данных Drools, делая ее исполняемой механизмом

Внедрение исполняемой модели приносит множество преимуществ в различных областях:

  • Время компиляции : в Drools 6 кьяр содержал список файлов drl и других артефактов Drools, определяющих базу правил, вместе с некоторыми предварительно сгенерированными классами, реализующими ограничения и последствия. Эти drl-файлы необходимо было проанализировать и скомпилировать с нуля, когда kjar загружается из репозитория Maven и устанавливается в KieContainer, что делает этот процесс довольно медленным, особенно для больших наборов правил. И наоборот, теперь можно упаковать внутри kjar классы Java, реализующие исполняемую модель базы правил проекта, и значительно быстрее воссоздать KieContainer и его KieBases из него. В процессе компиляции kie-maven-plugin автоматически генерирует источники исполняемой модели из файлов drl.
  • Время выполнения : в исполняемой модели все ограничения определены как лямбда-выражения Java. Те же самые лямбды также используются для оценки ограничений, и это позволяет избавиться как от mvel для интерпретированной оценки, так и от процесса джиттинга, преобразующего ограничения на основе mvel в байт-код, что приводит к медленному процессу прогрева.
  • Дальнейшие исследования : исполняемая модель позволит экспериментировать с новыми функциями движка правил без необходимости кодировать их в формате drl и изменять синтаксический анализатор drl для их поддержки.

Выполняемые модели DSL

Одна из целей при разработке первой итерации DSL для исполняемой модели заключалась в том, чтобы избавиться от понятия шаблона и рассматривать правило как поток выражений (ограничений) и действий (последствий). По этой причине мы назвали его Flow DSL. Некоторые примеры этого DSL доступны здесь .

Однако после реализации Flow DSL стало ясно, что решение об отказе от явного использования шаблонов вынудило нас реализовать некоторую дополнительную логику, которая имела сложность и затраты на производительность, поскольку для правильного воссоздания структур данных, ожидаемых Drools compiler необходимо собрать воедино шаблоны из этих явно не связанных выражений.

По этой причине было решено повторно ввести шаблоны во второй DSL, который мы назвали Pattern DSL . Это позволило обойти этот алгоритм, группирующий выражения, который должен заполнить искусственный семантический пробел и который также занимает много времени во время выполнения.

Мы считаем, что оба DSL действительны для разных вариантов использования, и тогда мы решили сохранить и поддержать оба. В частности, шаблон DSL безопаснее и быстрее (даже если он более подробный), поэтому это будет DSL, который будет автоматически генерироваться при создании kjar с помощью kie-maven-plugin. С другой стороны, Flow DSL более лаконичен и ближе к тому, как пользователь может захотеть программно определить правило в Java, и мы планировали сделать его еще менее подробным, автоматически генерируя через постпроцессор части модели, определяющие индексация и свойство реактивности. Другими словами, мы ожидаем, что Pattern DSL будет написан машинами, а Flow DSL в конечном итоге — человеком.

Программная сборка

Как видно из тестовых примеров, описанных в предыдущем разделе, можно программно определить в Java одно или несколько правил, а затем добавить их в модель с помощью свободно распространяемого API.

1
Model model = new ModelImpl().addRule( rule );

Если у вас есть эта модель, которая, как объяснено, полностью независима от алгоритмов и структур данных Drools, из нее можно создать KieBase следующим образом.

1
KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );

Кроме того, можно также создать исполняемый kieproject на основе модели, начиная с простых файлов drl, добавляя их в KieFileSystem как обычно

1
2
3
4
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem()
                      .write( "src/main/resources/r1.drl", createDrl( "R1" ) );
KieBuilder kieBuilder = ks.newKieBuilder( kfs );

а затем построение проекта с использованием новой перегрузки метода buildAll (), который принимает класс, указывающий, какой тип проекта вы хотите построить

1
kieBuilder.buildAll( ExecutableModelProject.class );

При этом KieBuilder сгенерирует исполняемую модель (на основе Pattern DSL), а затем результирующий KieSession

1
2
3
KieSession ksession = ks.newKieContainer(ks.getRepository()
                                           .getDefaultReleaseId())
                        .newKieSession();

будет работать с ограничением на основе лямбда-выражений, как описано в первом разделе этого документа. Таким же образом можно также генерировать исполняемую модель из Flow DSL, передав другой класс проекта в KieBuilder.

1
kieBuilder.buildAll( ExecutableModelFlowProject.class );

но, что объясняется при обсуждении двух разных DSL, для этой цели лучше использовать основанный на шаблонах.

Плагин Kie Maven

Чтобы сгенерировать kjar, встраивающий исполняемую модель с помощью плагина kie-maven, необходимо добавить зависимости, относящиеся к двум ранее упомянутым проектам, реализующим модель и ее компилятор, в файл pom.xml:

01
02
03
04
05
06
07
08
09
10
<dependencies>
 <dependency>
   <groupId>org.drools</groupId>
   <artifactId>drools-model-compiler</artifactId>
 </dependency>
 <dependency>
   <groupId>org.drools</groupId>
   <artifactId>drools-canonical-model</artifactId>
 </dependency>
</dependencies>

также добавьте плагин в раздел плагинов

01
02
03
04
05
06
07
08
09
10
<build>
 <plugins>
   <plugin>
     <groupId>org.kie</groupId>
     <artifactId>kie-maven-plugin</artifactId>
     <version>${project.version}</version>
     <extensions>true</extensions>
   </plugin>
 </plugins>
</build>

Пример файла pom.xml, уже подготовленного для создания исполняемой модели, доступен здесь . По умолчанию kie-maven-plugin все еще генерирует kjar на основе drl, поэтому необходимо запустить плагин со следующим аргументом:

1
-DgenerateModel=<VALUE>

Где <VALUE> может быть одним из трех значений:

1
2
3
YES
NO
WITHDRL

И YES, и WITHDRL сгенерируют и добавят к kjar использование классов Java, реализующих исполняемую модель, соответствующую файлам drl в исходном проекте, с той разницей, что первое исключит файлы drl из сгенерированного kjar, а второе также добавит их , Однако во втором случае файлы drl будут играть только роль документации, поскольку KieBase будет построена из исполняемой модели независимо.

Будущие разработки

Как и ожидалось, одной из следующих целей является сделать DSL, особенно потоковый, более удобным для пользователя, в частности, генерируя с постпроцессором все части, которые могут быть автоматически выведены, например, связанные с индексами и реактивностью свойств.

Ортогонально по сравнению с исполняемой моделью мы улучшили модульность и согласованность правил, особенно благодаря работе, выполняемой над блоками правил. Этот акцент на pojo-ification дополняет это направление исследований вокруг чистых java DSL, и у нас уже есть несколько простых примеров того, как исполняемая модель и Единицы правила могут быть смешаны для этой цели.

Смотрите оригинальную статью здесь: Исполняемая модель Drools жива

Мнения, высказанные участниками Java Code Geeks, являются их собственными.