pandaadb
pandaadb

Reputation: 6456

Drools loading session seems to fire rules

I am at a loss with this and can't seem to find an answer in the docs. I am observing the following behaviour. I have this rule:

import function util.CSVParser.parse;

declare Passenger 
    @role(event)
    @expires(24h)
end

rule "Parse and Insert CSV"

    when
        CSVReadyEvent( $csv_location : reader ) from entry-point "CSVReadyEntryPoint";
        $p : Passenger() from parse($csv_location);
    then
        insert( $p );

end

I can then enter my CSVReadyEvent into my session and call fireAllRules and it executes correctly. It hits the safe point at the end, and all is cool.

I then restart my app and load the session like this:

KieSession loadedKieSession = kieServices.getKieService().getStoreServices().loadKieSession(session.getId(), kieBase, ksConf, kieServices.getEnvironment());

The base and config I take from my kmodule.xml.

What happens now is that WITHOUT calling fireAllRules() loading the session somehow triggers fireing all rules.

I do not understand how unmarshalling triggers rule execution but this is obviously wrong. I have already executed that rule, and it should not be executed twice.

In a test case (my tests do NOT create persistent sessions because I only want the rules to be tested) I can call fireAllRules() twice, and the second time does not trigger any matched rules. I am not exactly sure what goes wrong, but the persistent session seems to be loaded in an odd way. Or the persisting of the session is wonky and forgets that it had executed the rule already.

Does anyone have inside in this? I am more than happy to share any code.

Here's my persistence.xml:

<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <class>org.drools.persistence.info.SessionInfo</class>
        <class>org.drools.persistence.info.WorkItemInfo</class>

        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.max_fetch_depth" value="30" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />
        </properties>
    </persistence-unit>

Thanks!

Upvotes: 0

Views: 781

Answers (2)

pandaadb
pandaadb

Reputation: 6456

An update/answer from a painful painful painful day of debugging and testing and running stuff:

  1. I suspected my hibernate setup was wrong, so the wrong thing got persisted. I ended up throwing that approach away and writing a manual marshalling/de-marshalling thing.

After creating/loading/recreating/loading I can confirm the session NEVER changes on file.

This was interesting to me because I could swear that the rules are executed, and I was half right:

The WHEN part is executed when the session is loaded. Why? I have not the slightest idea... I was chasing a red hearing because I am calling a function in my when part (as you can see in the rule) to iterate and insert all facts based on that event I am receiving.

My parse function obviously has logging, so each time I reload the session, I get a storm of log flying through my terminal hinting that my rules are being executed.

I then changed my rules to be very very specific (as in output everywhere I possible can). I debugged as deep as I could and I still can't seem to be able to pinpoint as to why on earth recreating the session is executing the when part of a rule. I settled on this: Magic. And with a little more detail:

The documentation of drools persistence https://docs.jboss.org/jbpm/v6.2/userguide/jBPMPersistence.html states that the guys implemented their own serialze/deserialize strategy in order to speed up the process. I resolve to blame this custom strategy on what I am seeing.

Lesson learned:

  • Do NOT create objects in the when part (because this will slow you down when loading a session since all when parts are executed)
  • Chasing red herrings is a pain in my butt.

So to sum up: I believe (up to say 99%) that loading a session is NOT executing the rules.

Upvotes: 1

laune
laune

Reputation: 31300

Using events in real mode and in a STREAM session running due to fireUntilHalt on the one hand and saving and restarting sessions with fireAllRules are somewhat contradictory paradigms.

If you have events, I suggest that you use the API to set up and start a (stateful) session in a thread, and insert facts (events) as they arrive.

Upvotes: 0

Related Questions