Question

In my company we are planning to use Drools a BRE for couple of projects. Now we trying to define some best-practices.

My question is what should be and shouldn't be done inside a Rule Condition/Consequence. Given that we can write Java directly or call methods (for example From a Global object in the Working Memory).

Example. Given a Rule that evaluates a generic Object (e.g. Person) have property set to true. Now, that specific propertie can only be defined for that Object going to the database and fetching that info. So we have two ways of implementing that:

Alternative A:

  • Go to the database and fetch the object property (true/false, a code)
  • Insert the Object in the working memory
  • Evaluate the rule

Alternative B:

  • Insert a Global Object that has a method that connects to the database and check for the property for the given object.
  • Insert the Object to eval in Working Memory
  • In the rule, call the Global Object and perform the access to the database

Which of those is considered better? I really like A, but sometimes B is more straightforward, however what would happen if something like a Exception from the Database is raised?

I have seen the alternative B implemented in the Drools 5.0 Book from Packt Publishing,however they are doing a mocking and they don't talk about the actual implications of going to the database at all.

Thank you,

Was it helpful?

Solution

I also have a need to grab external data from other system (database, service calls, etc) so I've dealt with this a bit. Personally, I would make that decision based on whether you will know what facts you will need up front. If so, then by all means, feel free to make your calls in Java. This will allow you to do better error handling. And if not being able to retrieve certain data means that running the rule engine is a no-go, you will avoid the work of creating the session, inserting facts, setting globals and so on. No sense in starting it if you're just going to halt().

But of course there are also cases where not being able to retrieve data shouldn't stop you from running. In some of those cases, Alternative A and B would work equally well. But suppose that needing certain data depends on other things. For example, I work on an application that evaluated what are essentially big logic trees and the leafs are evaluated using data from service calls. If two leafs were AND'd together so both had to be true for their branch to be true, as soon as one of them evaluated to false, that branch becomes false and I no longer need to evaluate the other leaf. That means that it would have been a waste to have pre-loaded the data I would have needed to evaluate it. Retrieving data "on demand" is one reason that rule engines like Jess also support backward chaining in addition to the default forward chaining.

Until backward chaining is complete in Drools, the alternative I've seen suggested is using the "from" keyword. I've had some luck with it but there are two things to consider:

  1. Drools queries the "from" statement repeatedly while the rule engine runs. I use caching in my service layer so this is only as harmful as a HashMap lookup, but if you don't cache, you run the risk of unknowingly making dozens, hundreds or thousands of service calls.
  2. If you don't find the data you expected, there isn't a place to do error handling. This is kind of what Steven Herod alluded to. The rule engine will carry on and it will keep evaluating the expression you gave it. In situations where I needed to take some action like calling halt(), I made the service call in the rule's consequence instead.

I hope this helps. Let me know if there's anything I can clarify or expand on.

OTHER TIPS

One of the things about rules is that they can be executed many, many times. Particularly if you make an error with your rule conditions. That obviously has a performance impact.

I'm inclined then to prefer option A, prepare your facts outside, and insert them into working memory for evaluation.

Certainly, there is also the option of partitioning the rules into data loading rules then business rule evaluation (using Rule flow for instance).

That would give you declarative control of populating your data outside of code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top