Запуск OptaPlanner в AWS Lambda выдает ошибку, связанную с AlphaNetworkCompilation

Я пытаюсь запустить решатель Optaplanner (8.20.0) в AWS Lambda, загруженный в толстую банку со всеми зависимостями. При запуске решения (или, точнее, при создании решателя: на SolverFactory.create() я сталкиваюсь со следующей ошибкой:

  [ ... snip - large list of "Cannot find symbol" / "Cannot find package" errors ... ]
  location: class org.drools.ancompiler.CompiledPACKAGE_LOCATION_domain_ParticipationNetwork41408373267, org/drools/ancompiler/CompiledPACKAGE_LOCATION_domain_ParticipationNetwork41408373267.java (95:16) : cannot find symbol
  symbol:   variable objectTypeNode
  location: class org.drools.ancompiler.CompiledPACKAGE_LOCATION_domain_ParticipationNetwork41408373267, org/drools/ancompiler/CompiledPACKAGE_LOCATION_domain_ParticipationNetwork41408373267.java (99:16) : cannot find symbol
  symbol:   variable objectTypeNode
  location: class org.drools.ancompiler.CompiledPACKAGE_LOCATION_domain_ParticipationNetwork41408373267]
    at org.kie.memorycompiler.KieMemoryCompiler.compileNoLoad(KieMemoryCompiler.java:136)
    at org.kie.memorycompiler.KieMemoryCompiler.compileNoLoad(KieMemoryCompiler.java:104)
    at org.kie.memorycompiler.KieMemoryCompiler.compile(KieMemoryCompiler.java:56)
    at org.kie.memorycompiler.KieMemoryCompiler.compile(KieMemoryCompiler.java:42)
    at org.drools.ancompiler.KieBaseUpdaterANC.inMemoryUpdate(KieBaseUpdaterANC.java:66)
    at org.drools.ancompiler.KieBaseUpdaterANC.run(KieBaseUpdaterANC.java:52)
    at org.drools.ancompiler.KieBaseUpdaterANC.generateAndSetInMemoryANC(KieBaseUpdaterANC.java:99)
    at org.optaplanner.core.impl.score.director.stream.DroolsConstraintStreamScoreDirectorFactory.buildKieBaseFromModel(DroolsConstraintStreamScoreDirectorFactory.java:115)
    at org.optaplanner.core.impl.score.director.stream.DroolsConstraintStreamScoreDirectorFactory.buildKieBase(DroolsConstraintStreamScoreDirectorFactory.java:104)
    at org.optaplanner.core.impl.score.director.stream.DroolsConstraintStreamScoreDirectorFactory.<init>(DroolsConstraintStreamScoreDirectorFactory.java:71)
    at org.optaplanner.core.impl.score.director.stream.ConstraintStreamsScoreDirectorFactoryService.lambda$buildScoreDirectorFactory$0(ConstraintStreamsScoreDirectorFactoryService.java:50)
    at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.decideMultipleScoreDirectorFactories(ScoreDirectorFactoryFactory.java:115)
    at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildScoreDirectorFactory(ScoreDirectorFactoryFactory.java:52)
    at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildScoreDirectorFactory(DefaultSolverFactory.java:168)
    at org.optaplanner.core.impl.solver.DefaultSolverFactory.<init>(DefaultSolverFactory.java:78)
    at org.optaplanner.core.api.solver.SolverFactory.create(SolverFactory.java:122)
[ ... snip - trace of my code before calling SolverFactory.create() ... ]

Кажется, я проследил проблему до компилятора Alpha Network в памяти, присутствующего в Drools. В частности, отключение DroolsAlphaNetworkCompilationEnabled, как предлагается в этот ответ, решает мою проблему. Однако проблема нет, похоже, заключается в том, что AWS Lambda не предоставляет компилятор Java. Во-первых, ошибка в связанной проблеме отличается, а во-вторых, этот вопрос (не связанный с optaplanner), похоже, предполагает, что функции AWS Lambda могут компилировать классы с некоторыми хаками пути к классам во время выполнения.

Мои вопросы:

  1. Как влияет на производительность установка для DroolsAlphaNetworkCompilationEnabled значения false (что в настоящее время устраняет мою проблему)?
  2. Есть ли способ избежать DroolsAlphaNetworkCompilation в памяти? Копание в некоторых исходных файлах привело меня к KieBaseUpdaterANC.java в компилятор alphanetwork drools, который поддерживает опцию LOAD и загружает скомпилированную сеть из KJar. Однако DroolsConstraintStreamScoreDirectorFactory вызывает generateAndSetInMemoryANC, что вызывает компиляцию в памяти. Это может быть тот же вопрос, что и СЛЮНИ-5990
  3. В крайнем случае, является ли хак classpath-compiler-hack, предложенный в этот ответ, каким-либо образом применимым или реализуемым в моем случае использования optaplanner/drools?
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Запись 1: влияние на производительность может быть значительным. Мы видели снижение производительности до 50 %, но YMMV. Это будет сильно зависеть от решаемой проблемы.

Запись 2: Вы смогли отключить ANC через конфигурацию решателя. Это официально поддерживаемый вариант, и вам не нужно искать какой-либо другой.

Запись 3: Я не вижу способа подключиться к нашему собственному ANC с помощью взлома, подобного упомянутому. Может быть, использование Quarkus, который может выполнять эту компиляцию во время сборки проекта, а не во время выполнения, могло бы решить вашу проблему?

С учетом всего сказанного, эта ошибка не должна появляться в первую очередь. Посмотрим, есть ли что сказать по этому поводу ребятам из Drools.

Спасибо! Что касается 1, я понимаю, что это зависит от ситуации, но есть ли что-нибудь с точки зрения кода, которое помогает в этой ситуации? Определенные типы ограничений и т.д.? Мой главный вопрос в Q2 заключался в том, можно ли заменить отключение ANC в памяти в optaplanner загрузкой предварительно скомпилированного kjar. Или это можно сделать с помощью кварка, как вы предлагаете? Если возможно, я бы предпочел избежать этого - в настоящее время у меня нет этого слоя, и добавить его только для того, чтобы компиляция работала, кажется тяжелым. Но я надеюсь получить известие от кого-нибудь из команды Drools!

Radical 09.05.2022 21:54

Запись 1 - как правило, чем больше вы используете groupBys и расширенные соединения, тем больше влияние ANC будет омрачено влиянием этих конструкций. Запись предварительно скомпилированные JAR-файлы — действительно, это то, что мы обычно решаем с помощью Quarkus.

Lukáš Petrovický 10.05.2022 09:36

Быстрое обновление, использование Quarkus вокруг моей лямбда-функции действительно решает проблему и позволяет мне запускать OptaPlanner без отключения ANC.

Radical 12.05.2022 11:53

Другие вопросы по теме