The Life Cycle of a Typical Rule Execution Request
The main steps of a typical rule execution request in an application are as follows:
- Create a Rule Application Reference
- Create a Rule Session and pass it the Rule Application Reference
- Set rule execution settings or end point overrides for the Rule Session
- Create an Entity which will be used to pass data (state) to the rule engine
- Execute Rules against the data
- Work with output
The code for a sample rule execution is included below:
public string RunRules(string xmlInput)
// Create rule application reference
var ruleApp = new FileSystemRuleApplicationReference(@"C:\RuleApps\MyRuleApplication.ruleappp");
// Create a rule session
using (var session = new RuleSession(ruleApp))
// Adjust settings or endpoint overrides if needed
// Create at least one entity
var entity = session.CreateEntity("MyEntity", xmlInput);
// Execute auto rules
// Return output -- this example extracts XML
Step 1 - The Rule Application Reference
The Rule Application Reference is an object that points to a rule application. A rule application is a collection of rule sets along with the data schemas and end point definitions that support those rule sets. The reference contains enough meta-data so that rules can be loaded and compiled on demand, or reused from the Rule Application Cache if already previously compiled. The Rule Application Reference has three implementations which can be used to load rules from various sources:
- CatalogRuleApplicationReference - refers to a rule application stored in irCatalog®
- FileSystemRuleApplicationReference - refers to a rule application stored on a Windows file system
- InMemoryRuleApplicationReference - refers to a rule application read into memory from any source that can produce rule application XML, such as a content management system or database
Step 2 - The Rule Session
- The Rule Session is the main point of interaction between custom SDK integration code and the rule engine
- The Rule Session requires a Rule Application Reference that is defined in Step 1 above. The rule applications used by the reference are typically created with irAuthor®; however they can also be built using a custom authoring solution built against irSDK or the InRule embeddable authoring controls.
- Note that the RuleSession implements IDisposable, and should be explicitly or implicitly Disposed after it is no longer used. For stateless architectures, the .NET Using block is recommended. For stateful architectures, the RuleSession should be disposed when deemed no longer necessary by the given session management solution.
Step 3 - Execution Settings and End Point Overrides
- There are several execution settings that control cache, execution, and parallelism behaviors. In general the default settings should be used, but if necessary they can be overridden before executing any rules in the rule session
- If web service or database endpoints are used in rules, then the URLs and connection strings can be overridden for any given environment. This allows different services or databases to be used in different environments without the need to update rules. All end point overrides should be applied before executing rules.
Step 4 - Create an Entity
At least one "root" entity must be created that will allow the rule engine to communicate with data that is passed to the rules. The rule engine will automatically create child entities as necessary, so those entities do not need to be explicitly created.
InRule supports a variety of ways with which the rule application schema can be defined. The schema definition type chosen also dictates the ways with which the state can be passed into the engine. The schema for a rule application can be defined the following ways:
- Schema can be imported from one or more .NET assemblies. This schema model facilitates passing state to the rule engine via .NET object instances.
- Schema can be imported from an XSD. This schema model will result in the developer passing state as an XML documents or strings.
- Schema can also be defined ad-hoc in irAuthor. State is then defined using the RuleSession class to create Entities and set Field values or passing in XML or JSON.
- Schema can be imported from Microsoft® Dynamics® CRM if using the irX® authoring add-in. This schema model will be backed by XML during runtime.
Generally speaking, there are some relevant statements worth mentioning about schema definition and state models:
- Often, an external schema definition will already exist. Importing an external definition as the rule application schema will enforce consistency between the calling application and InRule. Rule applications with an imported schema require a manual 're-sync' each time the external definition is adjusted. This forces users of InRule to verify that introduced schema changes do not cause issues with existing rule logic.
- Building an ad-hoc schema can be an agile approach to working with a rule application. However it may cause additional effort to map state values between external state objects and InRule state. For example, if a rule author builds existing fields into a rule application schema, the developer is often accountable for seeing that those extra fields are mapped to corresponding input/output values for the calling application.
- Importing the schema from a .NET assembly adds the ability to call instance methods in the classes from rules. Further, passing state to the engine is straightforward because the rule session will accept a .NET object graph. During rule execution, the rule engine reads values from the object graph using the class's Get property accessors. Likewise, the rule engine will write object graph values using the class's Set property accessors.
- Importing from either .NET assembly or XSD will allow entities and fields to be individually aliased. During the import setup, individual entities and fields can also be included or excluded from the import.
Step 5 - Execute Rules
Now that the Rule Session is populated, rules can now be executed against the data that was provided to the Rule Session.
Most rule applications contain groups of rules defined as a series of "rule sets". A rule set is simply a group of rules. The exact rule sets that are executed and the order in which rules are executed are dependent on the fire modes, run modes, and data context of the given rule sets that are contained within a rule application.
Rule Sets can be set to one of two "fire modes":
- Auto - The rule set will be available to automatically fire at least once for each instance of the entity type to which the rule set is associated. Depending on the "run mode" and "activation" settings of the rule set, the rule set may fire more than once or not fire at all.
- Explicit - The rule set will never fire automatically. It will only fire if explicitly invoked by a call to the InRule SDK, or when invoked by another rule.
The firing behavior of auto rule sets can be controlled by setting the "run mode" of the auto rule set:
- Optimized - Rules within the rule set may not fire in authored order, but are instead fired in the fastest order as determined by the rule engine. Rules may fire more than one time if values that they previously consumed are modified by another rule.
- Sequential - Rules within the rule set fire in authored order. The entire rule set (sequence) may fire more than one time if values that were previously consumed by the rule set are modified by other rules.
- Single Pass Sequential - Rules within the rule set fire in authored order. The rule set will not re-fire based on data changes made by subsequent rules.
The following additional rule constructs are also supported by InRule. These rules are always set to fire automatically (fire mode "auto"), and they may re-fire if the values that they previously consumed are modified by another rule.
The number of instances of a given rule and the data against which it operates is based on the "context" of that rule. In InRule, rules can be authored in the context of an entity or a field, or with no data context. If a rule or rule set is authored within the context of an entity or field, an instance of that rule set or rule is created and evaluated for each instance of the entity or field that is present within the given rule session. If a rule has a data context, it is evaluated against the entity instance with which it is associated.
InRule also supports authoring rules with no entity or field context. These rule sets are called "independent rule sets". An independent rule set must have data passed to it when it is invoked, since it has no inherent data context with which to begin reading data fields.
Rule execution can be initiated using one of three methods in irSDK:
- RuleSession.ApplyRules - Executes all "auto" rules against entity instances that have been added to the rule session. If auto rule sets contain rules that invoke explicit rule sets, then those explicit rule sets will also fire.
- RuleSession.ExecuteIndependentRuleSet - Executes a specific independent rule set given input arguments passed in the call. Any auto rules that are applicable will also fire.
- Entity.ExecuteRuleSet - Executes a specific explicit rule set against a given entity instance. If the rule set accepts parameters, then parameters can be passed in the call. Any auto rules that are applicable will also fire.
Rule Execution Order and Frequency of Rule Execution
During an ApplyRules request, the engine fires all Optimized and Sequential rule sets before firing any Single Pass Sequential rule sets. The Optimized and Sequential rule sets fire in the order that they are discovered as the engine reads in root entities and related child entities. Single Pass Sequential rule sets are fired last in the order that they were discovered during the initial read of entities.
When an ExecuteIndependentRuleSet or ExecuteRuleSet call is invoked, all Optimized and Sequential rule sets fire first in the order that they are discovered, followed by the explicit rule set that has been requested in the call. Finally, any Single Pass Sequential rule sets are fired in the order that they were discovered during the initial read of entities.
Other types of auto rules, such as Calculations, Classifications, and Constraints, are fired on demand as they are consumed by other rules or rule engine state reads.
If a RuleSession is reused for more than one request, then all Single Pass Sequential rule sets will re-fire on each subsequent rule request that is submitted to the same RuleSession. The following other "auto" rule types will re-fire only if the rule engine dependency network determines that some data change should cause them to re-fire:
- Sequential Rule Sets
- Optimized Rule Sets
Advanced Control over Rule Firing using Activation Settings
An advanced technique to control the firing of auto rule sets during rule execution is to employ an Activate/Deactivate pattern. This pattern can rely on the Activate Rule Set and Deactivate Rule Set actions in irAuthor, or rule sets can be activated and deactivated with code using irSDK.
When a rule set is activated it is added to the processing agenda of the rule engine so it is available to fire. When it is deactivated, it is removed from the agenda so that it will not fire. The rule author can control which "auto" rules are available for consideration at any point during rule processing by toggling the activation settings of rule sets.
Notes on activating or deactivating rule sets:
- Rule sets can be assigned to one or more 'Categories'. InRule contains actions for Activate/Deactivate by Category so that a rule author can activate or deactivate many different rule sets simultaneously based on the categories that are assigned to the rule sets.
- Explicit Rule Sets (which include Independent Rule Sets) also have properties for activation/deactivation. However, the rule compiler will not accept explicit rule sets as targets of activation or deactivation rules.
- Rule sets also contain a property for 'Enabled' which should not be confused as having similar functionality as 'Activated'. The 'Enabled' property cannot be controlled via irSDK or via irAuthor during rule execution. If a rule or rule set is not Enabled, it will not be included in the compiled rule application and will not be accessible in any way at runtime.
Step 6 - Consume Rule Engine Output
Once rule execution is complete the data that was passed into the rule engine is available for use elsewhere in the application. In the case of object instances, the actual object graph will be kept in sync during execution by the rule engine. XML or JSON data must be explicitly retrieved from the session.
In addition to the updated state data, the following are some of the more commonly used mechanisms to facilitate communication from the rule engine to the host application:
- Notifications - Messages generated by the Fire Notification action
- Validations - Error messages associated with a specific field or entity that are fired by the Mark Field Invalid action or constraints
- Rule Execution Log - The log contains execution information such as when there are state changes, which rules were fired and other runtime details
- Trace - If tracing was turned on in code, the trace file can be saved for review in irAuthor after execution completes. Please note that tracing is resource intensive and can significantly slow rule execution -- sometimes by more than a factor of ten. It is recommended that rule tracing is enabled only as needed, and not for every rule execution request. It is not recommended to use tracing for production applications.