Я пытаюсь запустить решатель 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 могут компилировать классы с некоторыми хаками пути к классам во время выполнения.
Мои вопросы:
KieBaseUpdaterANC.java
в компилятор alphanetwork drools, который поддерживает опцию LOAD и загружает скомпилированную сеть из KJar. Однако DroolsConstraintStreamScoreDirectorFactory
вызывает generateAndSetInMemoryANC
, что вызывает компиляцию в памяти. Это может быть тот же вопрос, что и СЛЮНИ-5990Запись 1: влияние на производительность может быть значительным. Мы видели снижение производительности до 50 %, но YMMV. Это будет сильно зависеть от решаемой проблемы.
Запись 2: Вы смогли отключить ANC через конфигурацию решателя. Это официально поддерживаемый вариант, и вам не нужно искать какой-либо другой.
Запись 3: Я не вижу способа подключиться к нашему собственному ANC с помощью взлома, подобного упомянутому. Может быть, использование Quarkus, который может выполнять эту компиляцию во время сборки проекта, а не во время выполнения, могло бы решить вашу проблему?
С учетом всего сказанного, эта ошибка не должна появляться в первую очередь. Посмотрим, есть ли что сказать по этому поводу ребятам из Drools.
Запись 1 - как правило, чем больше вы используете groupBys и расширенные соединения, тем больше влияние ANC будет омрачено влиянием этих конструкций. Запись предварительно скомпилированные JAR-файлы — действительно, это то, что мы обычно решаем с помощью Quarkus.
Быстрое обновление, использование Quarkus вокруг моей лямбда-функции действительно решает проблему и позволяет мне запускать OptaPlanner без отключения ANC.
Спасибо! Что касается 1, я понимаю, что это зависит от ситуации, но есть ли что-нибудь с точки зрения кода, которое помогает в этой ситуации? Определенные типы ограничений и т.д.? Мой главный вопрос в Q2 заключался в том, можно ли заменить отключение ANC в памяти в optaplanner загрузкой предварительно скомпилированного kjar. Или это можно сделать с помощью кварка, как вы предлагаете? Если возможно, я бы предпочел избежать этого - в настоящее время у меня нет этого слоя, и добавить его только для того, чтобы компиляция работала, кажется тяжелым. Но я надеюсь получить известие от кого-нибудь из команды Drools!