In the application that I'm working on right now, I need to periodically check eligibility of tens of thousands of objects for some kind of a service. The decision diagram itself is in the following form, just way larger:
In each of the end nodes (circles), I need to run an action (change an object's field, log information etc). I tried using Drool Expert framework, but in that case I'd need to write a long rule for every path in the diagram leading to an end node. Drools Flow doesn't seem to be built for such a use case either - I take an object and then, depending on the decisions along the way, I end up in one of the end nodes; and then again for another object. Or is it? Could you give me some examples/links to such solutions?
UPDATE:
Drools Flow calls might look like this:
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
Map<String, Object> params = new HashMap<String, Object>();
for(int i = 0; i < 10000; i++) {
Application app = somehowGetAppById(i);
// insert app into working memory
FactHandle appHandle = ksession.insert(app);
// app variable for action nodes
params.put("app", app);
// start a new process instance
ProcessInstance instance = ksession.startProcess("com.sample.ruleflow", params);
while(true) {
if(instance.getState() == instance.STATE_COMPLETED) {
break;
}
}
// remove object from working memory
ksession.retract(appHandle);
}
That is: I'd take an Application object, start a new process for it, when the process is finished (the final, action node would modify the application somehow), I'd remove the object from working memory and repeat the process for a new App object. What do you think about this solution?
SOLUTION:
I've ended up using Drools Flow and it has been working quite fine. My decision process isn't as straightforward as Drools Expert asks for and depending on where in the decision tree the process is it needs to load lists of objects from the database, transform them, make decisions, log everything etc. I use a Process object that is passed to the process as a parameter and stores all my global variables (for the process) and some convenience methods that are repeated at different points in the tree (as writing Java code in the Script Task
nodes isn't very convenient itself). I also ended up using Java to make decisions (and not mvel
or rules) - it's faster and I'd say easier to control. All objects that I work with are passed as parameters and used as normal Java variables in the code.
Drools expert is definitely the way to go.
If you want to avoid repeating yourself for the higher nodes, then the trick is to use insertLogical
(or just insert
if you're in a stateless session) and to understand that rules can trigger rules (It's not your father's SQL query). For example:
// we just insert Customer objects in the WM
rule "evaluateRetired"
when
$c : Customer(age > 65)
then
insertLogical(new Retiree($c));
end
rule "evaluteRetireeIsFemale"
when
$r : Retiree(customer.gender == Gender.FEMALE, $c : customer)
then
...
end
If the decision diagram frequently changes (and you want non-programmers to edit it), take a look at the documentation on decision tables (and DSL). In that case you'll probably repeat the entire path for each rule, but that's actually ok in most cases.