Drools - same KieSession for multiple requests

耗尽温柔 提交于 2021-02-08 10:13:04

问题


I use drools 6.3.0 in my projects. I have around 3 thousands rules with 2 categories. Say, category1 with 1500 rules and category2 with 1500 rules. There are 20k orders with different data. Each order will have set of different attributes. Now, creating kiesession for each request is taking time and it is really slow. So, planning to use the same kiesession for executing all the orders and orders will be processed using multi threading.

Below is my current approach.

 KieBase kieBase = null;
 KieServices kieServices = KieServices.Factory.get();
 KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(new KieModule() {
            @Override
            public ReleaseId getReleaseId() {
                return kieRepository.getDefaultReleaseId();
            }
        });

 KieFileSystem kfs = kieServices.newKieFileSystem();

 kfs.write(******);  // Load 3k rules in a for loop
 KieBuilder kb = kieServices.newKieBuilder(kfs);
            kb.buildAll();
 KieContainer kContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
 kieBase = kContainer.getKieBase();

 kContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
            kieBase = kContainer.getKieBase();
 KieSession kieSession = kieBase.newKieSession();

This is how i create kiesession and would like to use this kiesession for all the order execution.

I want to execute orders in parallel using thread pool.

This is how

// Here the entry is based on the category and some id. Each rule will have id and category. For each id and cateogory, there would be set of rules which should be evaluated.

The flow is like,

1) Take 20k orders from DB 2) For each order, get ids to be executed 3) For each id, format entry point like entry = id+_category

4) insert order attributes data and fireRules.

final EntryPoint entryPoint = ksession.getEntryPoint(entry);
        if (entryPoint != null) {
            entryPoint.insert(data);
            ksession.fireAllRules();
        } else {
            log.warn("No rules to be executed");
        }

Now, as i have to execute the orders in parallel,

Each order will call the below code in parallal,

entryPoint.insert(data);
ksession.fireAllRules();

Since, each order will have different attributes and inserting different data to entrypoint, it is causing problem and not getting the expected result.

Is there anyway to achieve this?

Thanks


回答1:


Not a super-expert but I'm looking into something similar and I think the answers are to either get those calls into a synchronized block...which really isn't parallel execution at all or to use a StatelessKieSession instead which will create a regular KieSession local to the execute call with its own working memory so it'll only have the data objects you pass into .execute(...).

Surprisingly it doesn't seem significantly more time-consuming to use the Stateless session when compared to reusing a single regular session and clearing the objects from it between firing the rules.




回答2:


Maybe you should use prototype sessions. In kmodule.xml file add:

<ksession name="YourSessionName" type="stateful" default="false" clockType="realtime" scope="prototype"/>


来源:https://stackoverflow.com/questions/39772553/drools-same-kiesession-for-multiple-requests

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!