I am very new to Drools, and started with the basics. Here is a setup;
Have a few rule files
Rules in different files belong to different Agenda groups
All the rules operate on the same fact
In my Unit Test, I obtain a particular "Agenda Group", set Focus (session.setFocus)
I insert the fact (Here is where I notice the rules within the other agenda group are getting evaluated even though the focus is not on them)
I fireAllRules()
Shouldn't the rules pertaining to the particular agenda group that is in focus be fired and not all rules from all the groups?
It is a fundamental law in many Rule Based Systems - especially those that follow Rete or similar algorithms - that the evaluation of conditions ("t
when", "left hand side") happens whenever there are changes in Working Memory: inserts, updates or deletes. In contrast, rule firing or the execution of consequences ("then", "right hand side") happens after fireAllRules or fireUntilHalt has been called.
The firing of rules - more precisely: of activations of rules - can be controlled in several ways. Here, it is indeed the focussed agenda group that limits what can be executed by the engine.
Keep this in mind: evaluation is not equal to execution.
Related
I am using before update triggers to enforce some complex business rules.
One trigger has three separate checks, each running its own query.
Is this best implemented using:
a) a single before update trigger containing all three querys
b) three separate before update triggers each containing a single query
If all checks inside triggers are connected with business rules, then one trigger gives better (more redadable) structure of checks, better control over checks order, trigger can be terminated with error in any time without processing all checks, additionaly there is always place to reuse some information obtained during check in next one.
The same functionality can be achieved with multiple triggers, but execution order of those triggers may be not so obvious.
According to Documentation
If multiple triggers of the same kind are defined for the same event,
they will be fired in alphabetical order by name.
It' s worth mentioning, that placing complex business rules inside triggers is not recommended approach.
I am using drools in my project and assume it has 100 rules. I have two process flow (typically it has start node->rule flow task->end node). One process flow's rule flow task is specified with rule flow-group which is assigned to 50 rules and another process flow's rule flow task is specified with flow flow groups which is assigned to rest of the 50 rules. The don't overlap.
Now I use kiesession and call start process of first process flow, I see that it loads all the 100 rules instead of only 50 and gives me compilation and runtime errors. So please help me in understanding why rules from different rule flow groups are getting executed in a process flow where those rules are no where related its rule flow-group ? I see all its when conditions are getting loaded.
The "unit of work" in Drools is the KieBase and not the rule-flow-group. All the rules in your KieBase will be present in your KieSessions and will be evaluated when required.
Hope it helps,
For reusable perspective, I have one Rule with Rule Flow group. I have use same rule flow group multiple times in flow. Now the situation is its should be fire same rule more then one time,but its only fire that rule single time.
I don't understand why its happens.
Can you give me an idea why its happening and whats the solution for same?
A Rule Task in a flow does not "execute" the rules in a rule-flow-group, it merely activates that group in the agenda so IF there are active rules, they will fire.
If between 2 executions of your Rule Task you modify the session in a way that new activations are created, consecutive executions of your task should fire new activations of those rules.
Hope it helps,
How to Fire all the rules in drools regardless of which group it belongs to,
I have two Rule-flow groups i.e., "rules1" "rules2", How to fire all the rules without mentioning rule-flow group name? I want to apply all the rules.
This is not possible. If a rule is in a group, the group has to receive the focus - otherwise the rules won't fire.
However, it isn't difficult at all to add a rule that will set the focus to another group.
Also, you can write a very simple loop setting the focus to group after group and to fire all rules.
If you don't need the grouping, remove the rule attribute.
(I have also posted this question at math.stackexchange.com because I'm not sure where it should belong.)
I have a system with the following inputs:
Set of work items to be completed. These are variable sized. They do not have to be completed in any particular order.
Historical data as to how long work items have taken to complete in the past. However, past performance is no guarantee of future success! That is, once we come to actually execute a work item, we may find that it takes longer or shorter than it has previously.
There can be work items that I have never seen before and hence have no historical data about.
Work items further have a "classification" of "parallel" or "serial".
Set of "agents" which are capable of picking up a work item and working on it. The number of agents is fixed and known in advance. An agent can only work on one work item at a time.
Set of "servers" against which the agents execute work items. Servers have different capabilities. Specifically, they are capable of handling different numbers of agents simultaneously.
Rules:
If a server is being using to execute a "serial" work item, it cannot simultaneously be used to execute any other work item.
Provided a server isn't being used to execute any "serial" work items, it can simultaneously handle as many agents as it is capable of, all executing "parallel" work items.
There are a handful of work items which must be executed against a specific server (although any agent can do that). These work items are "parallel", if that matters. (It may be easier to ignore this rule for now!)
Requirement:
Given the inputs and rules above, I need to execute the set of work items "as quickly as possible". Since we cannot know how long a work item will take until it is complete, we cannot possibly hope to derive a perfect solution up front (I suppose), so "as quickly as possible" means not manifestly doing something stupid like just using one agent to execute each work item one by one!
Historically, I've had a very simple round-robin algorithm and simply sorted the work items by descending historical duration such that the longest running work items get scheduled sooner and, hopefully, at the end of the cycle I'm able to keep all agents and servers reasonably well loaded with short-duration work items. This has resulted in a pretty good "square" shape to the utilization graph with no long tail of long-duration work items hanging around at the end of the cycle.
This historical algorithm, however, has required me to pre-configure the number of agents and servers and pre-allocate work items to "pools" and assign pools to servers, and lots of other horrible stuff. I now need to support a dynamic number of agents and servers without having to reconfigure things. (Note that the number of servers will be fixed during a cycle - that is, the number will only change between cycles - but the number of agents may increase or decrease in the middle of the cycle.)
Once all work items are complete, we record how long each work item took to feed in to the next cycle and start again from the beginning!