Some people seem to be quite surprised to find that TIBCO BusinessEvents, classed as a Complex Event Processing product, includes a “rule engine”. Especially those that look at the CEP tools market and just see the stream-based CEP products doing continuous queries. Nonethless, there are good reasons why a production rule engine is ideal not just for business decisions, but also event filtering and correlation.
First, lets classify “rules” and “production rules”. Production rules are a type of rule that represent an “IF THEN” statement, but typically applied not to single data variables, but to classes of data (and events). Many commercial rule engines, including BusinessEvents, use developments of the Rete algorithm devised in the 1970s as an efficient pattern matching algorithm for dealing with multiple patterns and multiple data elements. The rule engines that use this algorithm typically provide “forward chaining” in that any rule’s action can update data tested in some other rule, and the rule engine can automatically fire the new rule too. The “interesting” aspect of this is that the rule engine determines when rules fire, not the programmer ordering the rules in some way. For this reason, production rules in rule engines are considered “declarative” – their execution is independent of the order they are defined, which makes design-time scalability easier. Needless to say, the Rete algorithm means that the cost of adding rules to a system is not linear – twice the rules take far less than twice the space and far less than twice the execution time.
The fact that production rules are defined in terms of classes adds another dimension in flexibility. These “declarations” in BusinessEvents, or RuleVariables in the OMG PRR standard, add runtime scalability – the same rule can execute for 1 or 1000 instances of a class, without any additional configuration.
So there are 3 basic parts of a (production) rule (used in a Rete-type rule engine): declaration/RuleVariables, condition, and action:
- Declarations extend the “scope” of a rule.
The declaration is a list of event types and classes to be used in the rule. At runtime each declaration matches against every instance (and the rule is therefore effectively compared to every combination of instances – or RuleVariable tuples).
Example: a declaration of CustomerCallEvent and ActiveCustomer for 2 CustomerCallEvents and 50 Customers will create 100 possible combinations or tuples to be considered. Adding a declaration of CustomerOrder with 100 instances increases this to 10,000 combinations or tuples.
This illustrates both the flexibility and potential cost of production rules – although of course the Rete algorithm can scale to very large tuple numbers.
- Conditions limit the “scope” of a rule.
The declarations are filtered and joined in the conditions. At runtime each combination of declated event types and data classes is filtered and joined to see if the rule is valid (and what instances of declarations pass the condition list).
Example: we may filter CustomerCallEvents to just those that are order-related, and associate them with the relevant ActiveCustomer and CustomerOrder. Only 1 CustomerCallEvent is order-related, matches to only 1 ActiveCustomer, and 2 CustomerOrders. Therefore we end up with 1 x 1 x 2 valid tuples or (potential) rule firings.
This illustrates how we can combine events and data in multiple ways, irrespective of event arrival order. Indeed, if we want to test a particular ordering of events, we have to add an explicit condition to handle that requirement.
- Actions execute the resultant event processing action or decision for a rule.
Typically, the actions will be executed for each set of declarations (tuple) that satisfy the condition part. Note that there is one additional runtime possibility here: the action for 1 instance can update the data used by another, making the condition fail.
Example: the action for the CustomerCallEvent and associated ActiveCustomer for the first CustomerOrder handles the event satisfactorily, abstracting it to a new event, and the action “consumes” (removes) the CustomerCallEvent. This means that the 2nd rule firing (for the same CustomerCallEvent and ActiveCustomer, but the 2nd CustomerOrder) is no longer valid as the CustomerCallEvent no longer exists. So this rule does not fire a 2nd time, in this case.
This illustrates the dynamic nature of rule processing. Where the rule also creates new events or updates existing data instances, then new rule firings may become possible (rule declarations and conditions become valid). This process, and the subsequent firing of other rules, is called rule inferencing.
- In addition, rules may have names, priority numbers and other metadata. Rule priorities are to aid in “conflict resolution”, a fancy term for what happens when 2 or more rules are valid to fire: which do we want to fire first?
For event processing purposes, the production rule format and inferencing rule engine has a number of advantages:
- Declarative rule definitions: I do not need to worry about the order I define my rules as this has no effect on their execution (except possibly where 2 rules can fire at the same time and I have not specified any priority – which normally means I don’t care). Adding new rules simply means adding them to a list, rather than worrying about where they need to be placed to be executed.
- Efficient declaration-based definitions: defining rules at the class level makes for generic rules that scale regardless of the number of instances I expect them to match against – indeed I may not know at design time the number of instances expected at runtime.
- Efficient pattern matching for rule conditions: the Rete-algorithm ensures (mostly) that runtime performance for event patterns, data patterns, and mixed event-data patterns is very good. All vendors have optimized their pattern matching for maximum performance (TIBCO is no exception with a combined code generation and Rete approach).
- Dynamic pattern behavior: condition filter statements can be defined as variables (or in BusinessEvents, scorecard entries) and adjusted on-the-fly by monitoring the results of other rules and processing.
So production rules enable the definition of arbitrarily complex and numerous event patterns. When combined with an event-aware rule engine, production rules provide an Event Condition Action (ECA) rule mechanism combining the features of business rule engines with event-driven behavior. The rules can represent basic raw event processing, complex (abstract) event processing, and event-based decision processing – using rulesets to differentiate these as appropriate! They can be combined with mechanisms like state models and query languages. They are a proven technology, and they work well.
 The difference between event-processing rules, event-driven rules, and rules for business decisions has been much-blogged-about. See these blogs by JT (twice!), Opher and Marco – the latter 2 pretty much covering the other, albeit ECA-based, rule-based CEP systems. In summary, of course, event-processing rules, event-driven rules, and rules for business decisions can all overlap, depending on the application.