问题
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