Visual Guide to Drools Rule Execution¶
This guide visually explains how the Drools rule engine processes your business rules and facts. By understanding the underlying mechanisms, you'll be better equipped to write efficient rules.
The Big Picture: How Drools Works¶
At a high level, Drools follows this sequence when processing rules:
graph TD
A[Define Rules] --> B[Insert Facts]
B --> C[Pattern Matching]
C --> D[Agenda Creation]
D --> E[Rule Execution]
E --> F[Update Working Memory]
F -->|If changes trigger rules| C
Let's break down each of these steps and understand what happens behind the scenes.
1. Inside the Rule Engine¶
The Drools rule engine has three key components that interact during rule processing:
graph LR
subgraph "Drools Rule Engine Components"
PM[Production Memory<br/>Stores Business Rules]
WM[Working Memory<br/>Stores Facts/Data Objects]
AG[Agenda<br/>Execution Queue & Order]
PM -->|Pattern Matching| WM
WM -->|Rule Activations| AG
AG -->|Execute Actions| WM
end
The three key components work together:
- Production Memory: Stores your business rules
- Working Memory: Stores your facts (data objects)
- Agenda: Determines which rules to execute and in what order
Here's a simplified view of how these components interact:
graph TD
A[Business Rules] --> B[Production Memory]
B -- Pattern Matching --> C
subgraph "Rule Engine"
C[Working Memory<br>Facts/Objects] --> D[Agenda]
end
D --> E[Rule Execution]
2. Pattern Matching Process¶
When facts are inserted into working memory, Drools needs to determine which rules should fire. This process is called pattern matching.
The Rete Network Evolution: From Rete to Phreak¶
Drools originally used the Rete algorithm (pronounced "REE-tee" or "RAY-tay") for pattern matching. Since Drools 6, it has been completely replaced by Phreak, an enhanced algorithm that provides:
- Lazy evaluation: Rules are only evaluated when needed
- Set-oriented propagation: Better performance with large data sets
- Improved memory usage: More efficient fact storage
- Better scalability: Handles thousands of rules and facts efficiently
While Phreak is architecturally different from Rete, the conceptual model remains similar, making it easier to understand rule execution.
Here's a simplified visualization of how a Rete/Phreak network might look for a rule:
graph TD
OTN[Object Type Nodes] --> A[Applicant]
OTN --> B[Loan]
OTN --> C[Credit]
OTN --> D[...]
A --> AN[Alpha Nodes<br>Property Constraints]
B --> AN
C --> AN
AN --> BN[Beta Nodes<br>Joins]
BN --> TN[Terminal Nodes<br>Rules]
Let's understand each node type:
- Object Type Nodes: Filter facts by their class type
- Alpha Nodes: Apply single-fact constraints (e.g.,
age > 18
) - Beta Nodes: Join multiple facts together (e.g.,
$a: Applicant() and $l: Loan(applicant == $a)
) - Terminal Nodes: Represent rules that are ready to fire
3. From Rule Definition to Execution¶
Let's walk through the lifecycle of a rule from definition to execution using a simple example:
Rule Definition¶
rule "Approve loan for good credit"
when
$application : LoanApplication(approved == false)
$applicant : Applicant(creditScore > 700)
then
modify($application) {
setApproved(true),
setReason("Good credit score")
}
System.out.println("Loan approved");
end
1. Rule Compilation¶
When you define rules like the one above, Drools compiles them into a network of nodes:
βββββββββββββββββββ
β Object Type β
β LoanApplicationβ
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Alpha Node β
β approved==falseβ
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββ
β Beta Network β
β β
ββββββββββββ΄ββββββββββ ββββββββββββ΄ββββββββββ
β Object Type β β Alpha Node β
β Applicant βββββββββββΆβ creditScore>700 β
ββββββββββββββββββββββ ββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β Terminal Node β
β (Rule Activation) β
βββββββββββββββββββββββ
2. Fact Insertion¶
When you insert facts, they flow through this network:
Applicant john = new Applicant("John", 30, 720);
LoanApplication johnApp = new LoanApplication(john, 50000);
kSession.insert(john); // Fact 1
kSession.insert(johnApp); // Fact 2
Both facts enter working memory and are processed through the network.
3. Pattern Matching and Agenda Creation¶
As facts flow through the network:
- The
LoanApplication
fact is checked against its constraints (not approved) - The
Applicant
fact is checked against its constraints (credit score > 700) - If both match, the rule is activated and placed on the agenda
graph LR
subgraph Agenda ["Rule Execution Agenda"]
A["β 'Approve loan<br/>for good credit'"]
end
4. Rule Execution¶
When you call fireAllRules()
, Drools executes the rules on the agenda:
The rule executes its action (the "then" part), which approves the loan application.
5. Working Memory Update¶
After rule execution, working memory is updated:
Working Memory (Before) Working Memory (After)
βββββββββββββββββββββββββ βββββββββββββββββββββββββ
Applicant(creditScore=720) Applicant(creditScore=720)
LoanApplication(approved=false) LoanApplication(approved=true)
6. Re-evaluation (if needed)¶
Because we used modify()
to change the loan application, Drools automatically re-evaluates any rules that might be affected by this change.
4. The Two-Phase Execution Cycle¶
When you call fireAllRules()
, Drools enters a two-phase execution cycle:
βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β β β β
β Agenda Evaluation Phase ββββββββΆ Working Memory Actions β
β β β Phase β
βββββββββββββββ¬ββββββββββββββββ βββββββββββββ¬ββββββββββββββββββ
β β
ββββββββββββββββββββββββββββββββββββ
- Agenda Evaluation Phase: The rule engine selects rules that can be executed.
- If no more rules can be executed, the cycle ends
-
If executable rules are found, they're registered in the agenda
-
Working Memory Actions Phase: The rule engine executes the consequences (actions) of activated rules.
- After all consequences are complete, or if
fireAllRules()
is called again, the process returns to the agenda evaluation phase
5. Conflict Resolution¶
What happens when multiple rules are eligible to fire? Drools uses conflict resolution strategies to determine the execution order:
Salience (Priority)¶
Rules with higher salience values fire before rules with lower values:
rule "High Priority Rule"
salience 100
when
// conditions
then
// actions
end
rule "Low Priority Rule"
salience 10
when
// conditions
then
// actions
end
In this example, the "High Priority Rule" will fire before the "Low Priority Rule" if both are activated.
Agenda Groups¶
Rules can be partitioned into agenda groups, and only rules in the focus group are eligible for execution:
graph TD
subgraph "Agenda"
A["Agenda Group: <br> 'calculation' (in focus)"]
B["β Rule 'Calculate tax'"]
C["β Rule 'Calculate discount'"]
D["Agenda Group: <br>'reporting'"]
E["β Rule 'Generate report'"]
F["β Rule 'Log transaction'"]
A --> B
A --> C
D --> E
D --> F
end
Only rules in the "calculation" group will fire until that group is empty or loses focus.
6. Stateful vs. Stateless Sessions Visualized¶
Stateful Session¶
A stateful session maintains facts across multiple fireAllRules()
calls:
βββββββββββββββββββββββ
β Stateful Session β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββββββ β βββββββββββββββ
β Applicant(John) ββββββββ€ insert(john)β
β β βββββββββββββββ
βββββββββββββ¬ββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββββββ β ββββββββββββββββββββ
β Applicant(John) ββββββββ€ insert(johnApp) β
β LoanApplication(...) β ββββββββββββββββββββ
βββββββββββββ¬ββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββββββ β ββββββββββββββββββββ
β Applicant(John) ββββββββ€ fireAllRules() β
β LoanApplication(...) β ββββββββββββββββββββ
β [AFTER RULE EXECUTION]β
βββββββββββββ¬ββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββββββ β ββββββββββββββββββββ
β Applicant(John) ββββββββ€ insert(mary) β
β LoanApplication(...) β ββββββββββββββββββββ
β Applicant(Mary) β
βββββββββββββ¬ββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββββββ β ββββββββββββββββββββ
β Applicant(John) ββββββββ€ dispose() β
β LoanApplication(...) β ββββββββββββββββββββ
β Applicant(Mary) β
β [SESSION DESTROYED] β
βββββββββββββββββββββββββ
Stateless Session¶
A stateless session processes all facts in a single operation and doesn't maintain state:
βββββββββββββββββββββββββ
β Stateless Session β
ββββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Insert all facts β βββββββββββββββββββββββββββ
β Execute all rules ββββββ€ execute([john, johnApp])β
β Dispose automaticallyβ βββββββββββββββββββββββββββ
βββββββββββββββββββββββββ
βββββββββββββββββββββββββ
β Stateless Session β
ββββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Insert all facts β βββββββββββββββββββββββββββ
β Execute all rules ββββββ€ execute([mary, maryApp])β
β Dispose automaticallyβ βββββββββββββββββββββββββββ
βββββββββββββββββββββββββ
Each execute()
call is a separate, isolated operation with no shared state between calls.
7. Truth Maintenance and Logical Insertions¶
Drools supports automatic truth maintenance through logical insertions. When you use insertLogical()
instead of insert()
, the fact is automatically retracted when the conditions that led to its insertion are no longer true.
Initial State
βββββββββββββββββββββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββ β
β Person(age=16) β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Rule "Infer Child" fires β
β when β
β $p : Person(age < 18) β
β then β
β insertLogical(new IsChild($p)) β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββ β
β Person(age=16) β
β IsChild(person=Person(age=16)) β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Update Person age β
β person.setAge(20) β
β update(factHandle, person) β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββββ β
β Person(age=20) β
β [IsChild fact automatically retracted] β
βββββββββββββββββββββββββββββββββββββββββββ
8. Event Processing in Drools¶
For time-based events, Drools supports two processing modes:
Cloud Mode (Default)¶
All events are treated as regular facts with no temporal constraints:
βββββββββββββββββββββββββββββββββββββββββββββ
β Working Memory (Cloud Mode) β
β βββββββββββββββββββββββββββ β
β StockTick(symbol="AAPL", price=150.00) β
β StockTick(symbol="MSFT", price=245.00) β
β StockTick(symbol="AAPL", price=152.00) β
β β
β [Events processed in insertion order β
β regardless of their time stamps] β
βββββββββββββββββββββββββββββββββββββββββββββ
Stream Mode¶
Events are processed with temporal awareness:
βββββββββββββββββββββββββββββββββββββββββββββ
β Working Memory (Stream Mode) β
β βββββββββββββββββββββββββββ β
β Time: 10:01:00 β
β StockTick(symbol="AAPL", price=150.00) β
β β
β Time: 10:02:00 β
β StockTick(symbol="MSFT", price=245.00) β
β β
β Time: 10:03:00 β
β StockTick(symbol="AAPL", price=152.00) β
β β
β [Events processed in chronological order] β
βββββββββββββββββββββββββββββββββββββββββββββ
9. Sliding Windows¶
In stream mode, you can define sliding windows of time or length to process only recent events:
Time Window¶
βββββββββββββββββββββββββββββββββββββββββββββ
β Sliding Time Window (2 minutes) β
β βββββββββββββββββββββββββββββ β
β β
β Current time: 10:03:00 β
β β
β In window: β
β ββββββββββ β
β StockTick(time=10:02:00, symbol="MSFT") β
β StockTick(time=10:03:00, symbol="AAPL") β
β β
β Outside window (expired): β
β βββββββββββββββββββββ β
β StockTick(time=10:01:00, symbol="AAPL") β
βββββββββββββββββββββββββββββββββββββββββββββ
Length Window¶
βββββββββββββββββββββββββββββββββββββββββββββ
β Sliding Length Window (last 2 events) β
β ββββββββββββββββββββββββββββββββ β
β β
β In window: β
β ββββββββββ β
β StockTick(time=10:02:00, symbol="MSFT") β
β StockTick(time=10:03:00, symbol="AAPL") β
β β
β Outside window: β
β βββββββββββββββ β
β StockTick(time=10:01:00, symbol="AAPL") β
βββββββββββββββββββββββββββββββββββββββββββββ
10. Temporal Operators¶
Drools supports temporal operators to define relationships between events:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Temporal Relationship: "after" β
β ββββββββββββββββββββββββββββ β
β β
β StockTick(symbol="AAPL", price=150) β β
β β β β
β β β β
β β βΌ β
β β StockTick(symbol="AAPL", price=152) β
β β β
β β β
β Event B occurs after Event A β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Drools supports many temporal operators including:
- after
/before
- coincides
- during
/includes
- finishes
/finished by
- meets
/met by
- overlaps
/overlapped by
- starts
/started by
11. Property Reactivity¶
By default, Drools only re-evaluates rules when properties that are actually used in constraints change:
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Rule: β
β "Approve high value customer" β
β when β
β Customer(status == "Gold", spending > 1000) β
β then β
β // Actions β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Working Memory β
β βββββββββββββ β
β Customer( β
β name="John", β
β age=35, β Changing this property β
β status="Gold", β Reactive property β
β spending=1200 β Reactive property β
β ) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
When you change the age
property, the rule isn't re-evaluated because the rule doesn't use it.
When you change status
or spending
, the rule is re-evaluated.
This gives you visibility into when: - Facts are inserted, updated, or deleted - Rules are activated or fired - Agenda groups are pushed or popped
Logging¶
Configure SLF4J logging to see detailed information:
This creates a log file that can be opened with the Audit View tool.
13. Life Cycle of a Drools Application¶
Here's the typical lifecycle of a Drools application:
graph TD
A[Define Facts Models] --> B[Author Rules]
B --> C[Insert Facts]
C --> D[Gather Rules Required]
D --> E[Determine Order to Fire]
E --> F[Fire Rules]
F --> G[Get Results]
G -->|Are there more rules <br> to process?| E
G -->|Done| H[Complete]
Summary¶
You've now seen how the Drools rule engine processes rules and facts. Understanding these internal mechanisms will help you:
- Write more efficient rules: By understanding how the pattern matching works, you can structure your rules for better performance
- Troubleshoot issues: When rules don't fire as expected, you know where to look
- Choose the right session type: Based on your use case, you can select stateful or stateless sessions
- Work with events: You can process time-based events using stream mode and sliding windows
The visual representations in this guide are simplified, but they provide a mental model of how Drools works under the hood. As you become more familiar with Drools, you'll develop an intuition for how changes to your rules and facts affect rule execution.
Remember that Drools is designed to separate business logic from application code. This separation makes your systems more maintainable and adaptable to changing requirements.