Handle long fireAllRules in Drools

Viewed 620

I currently ran into a problem in our Drools server.

We receive pretty large requests to our drools server farm that throws an OutOfMemoryError. Those large request shouldn't be process (they are bugs), and if a request takes more than 5s it should be canceled.

I've trying to workaround this with a custom timeout DRL rule has explained here:

    rule "Stop the rule engine after 5s"
        timer ( int: 5s )
        salience 0
    when
    then
        System.err.println("*** Stop the rule engine after 5s ***");
        drools.halt();
    end

But this rule is never taking into account. So I've tried another workaround: put my ksession.fireAllRules();in a thread, and if it takes more tahn 5 second, halt drools with ksession.halt();; like this:

    KieSessionConfiguration conf = kieServices.newKieSessionConfiguration();
    final KieSession ksession = kcontainer.newKieSession(conf);

    Thread droolsThread = new Thread(new Runnable() {
        public void run() {
            ksession.fireAllRules();                        
        }
    }, "drools");

    long tStart = System.currentTimeMillis();
    droolsThread.start();

    /*wait until the end of the Thread or 5 seconds max*/
    while (System.currentTimeMillis() - tStart < 5000 && droolsThread.isAlive())
        Thread.sleep(100);

    /*if alive for more than 5 seconds stop it*/
    if (droolsThread.isAlive())
    {
        System.err.println("timeout killing drools");
        ksession.halt();
        ksession.dispose();
    }

In this second scenario, when drools is called with the ksession.fireAllRules();, it starts executing the request, and if this a huge one throws the Exception: java.lang.OutOfMemoryError exception:

[apache-tomcat-9.0.39]: timeout killing drools
[apache-tomcat-9.0.39]:  Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Catalina-utility-1"
java.lang.OutOfMemoryError: Java heap space

I don't know what to do to stop those large request eating all the server memory. Is it possible to stop a long request currently running in drools?

2 Answers

You could use the following API on a StatefulRuleSession:

fireAllRules(int max) Fire Matches on the Agenda up to the given maximum number of Matches, before returning the control to the application.

On consuming memory, you could profile the memory usage (at the Java level) to see what is going on. Rule-based applications generally use a lot of memory from making a memory-processing time trade-off using algorithms derived from RETE

Related