Не удается сериализовать KieSession с несколькими правилами потоковой передачи в byte[]

Я сталкиваюсь с нереализованным случаем при сериализации моего KieSession в byte[]. Я храню свои правила в базе данных в формате byte[].

Вот фрагмент кода, который я использую для создания своего KieSession:

KieServices kServices = KieServices.Factory.get();

KieFileSystem kFileSystem = kServices.newKieFileSystem();

for(byte[] arr : myRules) {
    String fileName = "/src/main/resources/" + generateRandomRuleName();
    kFileSystem.write(fileName , new ByteArrayResource(arr ));
}

kServices.newKieBuilder(kFileSystem).buildAll();

У меня есть ~ 1K постоянных фактов, и после HTTP-запроса к моему приложению Spring Boot мне нужно скопировать мои KieSession байты, десериализовать их в KieSession, вставить ~ 1K временных событий, fireAllRules и удалить. Таким образом, я могу повторно использовать свои KieSession, не вставляя 1 КБ постоянных фактов в каждый HTTP-запрос или не удаляя 1 КБ временных фактов после каждого HTTP-запроса. Вот код, который я использую для сериализации моего KieSession:

KieBaseConfiguration configuration = KieServices.Factory.get().newKieBaseConfiguration();
configuration.setOption(MultithreadEvaluationOption.YES);
configuration.setOption(EqualityBehaviorOption.EQUALITY);
configuration.setOption(EventProcessingOption.STREAM);

KieBase kBase = kServices
        .newKieContainer(kServices.getRepository().getDefaultReleaseId())
        .getKieContainer()
        .newKieBase(configuration);

final KieSession kSession = kBase.newKieSession();

// myListOfPermanentFacts is an array of serializable Java objects, but not declared with @role ( fact )
kSession.execute((Command<?>) CommandFactory.newInsertElements(myListOfPermanentFacts));

final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
MarshallerFactory.newMarshaller(kBase).marshall(outputStream, kSession);
outputStream.close();
byte[] kSessionBytes = outputStream.toByteArray();

Когда у меня есть одно правило с from collect следующим образом:

rule "Rule_1"
    dialect "java"
    no-loop true
    when
        obj : MyObj( field1: field1 )
        List( size >= 3 ) from collect ( MyObj( field1 == field1, this before obj ) )
    then
        obj.someMethod( "string1" );
end

описанный выше вариант использования работает, как и ожидалось. Однако, когда у меня есть второе правило (очень похожее):

rule "Rule_2"
    dialect "java"
    no-loop true
    when
        obj : MyObj( field2: field2 )
        List( size >= 3 ) from collect ( MyObj( field2 == field2, this before obj ) )
    then
        obj.someMethod( "string2" );
end

Я получаю следующее исключение в методе marshall:

java.lang.UnsupportedOperationException: org.drools.core.common.CompositeDefaultAgenda.getActivations -> TODO
    at org.drools.core.common.CompositeDefaultAgenda.getActivations(CompositeDefaultAgenda.java:386) ~[drools-core-7.28.0.Final.jar:7.28.0.Final]
    at org.drools.core.marshalling.impl.ProtobufOutputMarshaller.evaluateRuleActivations(ProtobufOutputMarshaller.java:268) ~[drools-core-7.28.0.Final.jar:7.28.0.Final]
    at org.drools.core.marshalling.impl.ProtobufOutputMarshaller.serializeSession(ProtobufOutputMarshaller.java:135) ~[drools-core-7.28.0.Final.jar:7.28.0.Final]
    at org.drools.core.marshalling.impl.ProtobufOutputMarshaller.writeSession(ProtobufOutputMarshaller.java:115) ~[drools-core-7.28.0.Final.jar:7.28.0.Final]
    at org.drools.core.marshalling.impl.ProtobufMarshaller.marshall(ProtobufMarshaller.java:120) ~[drools-core-7.28.0.Final.jar:7.28.0.Final]
    at org.drools.core.marshalling.impl.ProtobufMarshaller.marshall(ProtobufMarshaller.java:104) ~[drools-core-7.28.0.Final.jar:7.28.0.Final]

С каким вариантом использования я сталкиваюсь, который еще не поддерживается? Спасибо.


person Hasan Can Saral    schedule 26.01.2021    source источник
comment
Это все еще проблема, если вы натыкаетесь на последнюю версию слюней? Между 7.28 и последней версией 7.x не должно быть ничего серьезного.   -  person Roddy of the Frozen Peas    schedule 26.01.2021
comment
@RoddyoftheFrozenPeas Я только что попробовал. Да, это так.   -  person Hasan Can Saral    schedule 26.01.2021


Ответы (1)


Он просто не реализован для CompositeDefaultAgenda, а CompositeDefaultAgenda используется MultithreadEvaluationOption.YES. Таким образом, установка значения MultithreadEvaluationOption.NO решает проблему.

Интересно то, что десериализация из byte[] в KieSession с моими постоянными фактами (которые я не хочу каждый раз вставлять заново) происходит намного медленнее, чем кэширование KieBase, создание нового KieSession и вставка этих постоянных фактов каждый раз.

person Hasan Can Saral    schedule 11.04.2021