-
Notifications
You must be signed in to change notification settings - Fork 341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: How to execute all the selected rules' actions instead of highest salience? #89
Comments
Looks like you are expecting something like Coming to the problem statement - i am not sure do we really require correct me if i am missing anything ? |
Yes, I think
If I combine all 20 or 3 rules together with a OR operator (i think that's the solution) it will only run the rule's action once. However each of these rules have their own unique/common set of actions and one trigger could fire off multiple rules=>actions combo |
I found that we have |
yes, lets have this thread open and see what others feel about |
Executing all matching rule's THEN statements could lead to un-necessary complexity.
To fulfil your case, I can think of couple work around. One simple thing you can do, to have a fact containing flags, a couple boolean attributes. Add this fact into data context and have the rules switch on and off those flags. When the rule ends, you know what is on, and what is off and execute some functions based on that. The benefit as follows
Rule engine is declarative computational approach and should be used for cases where often too complicated to do in conventional programming logic. There are DOs and DONTs when using Rule engine and cases where rule engine do best, meaning that its not a silver bullet of every thing. I advise you to read Martin Fowler's Rule Engine page. |
i really got your point and totally understand to make grule simple and robust. agree with you |
Thanks for the detailed explanation. I agree with you on all these points. As Martin says
It makes the system hard to reason about. In my case, the final actions are fairly simple and are acting as notifications and I think is a common requirement by these systems.
I also agree with the benefits of this approach. However as I understand your solution:
switching the flags on and off is only possible and must occur during THEN statement, which runs if the rule conditions are met and that rule has the highest priority. Which brings me back to my original problem, that is I can not switch those flags for every rule but only one (even though the engine goes through all the rules' conditions once, it only execute one singular selected rule). |
A bunch of facts. type Flags struct {
RuleA bool
RuleB bool
RuleC bool
RuleD bool
}
type Fact struct {
Name string
} Then, we specify some rule, Between these rule they have a "chaining" mechanism. rule RuleA "Turn On RuleA flag if condition is met" {
when
Flags.RuleA == false &&
Fact.Name == "George"
then
Flags.RuleA = true;
Retract("RuleA");
}
rule RuleB "Turn On RuleB flag if condition permit" {
when
Flags.RuleB == false &&
Fact.Name == "George"
then
Flags.RuleB = true;
Retract("RuleB");
}
rule RuleC "Turn On RuleC flag if some fact are ok" {
when
Flags.RuleC == false &&
Fact.Name == "Lucy"
then
Flags.RuleC = true;
Retract("RuleC");
}
rule RuleD "Turn On RuleD flag when necessary" {
when
Flags.RuleD == false &&
Fact.Name == "Lucy"
then
Flags.RuleD = true;
Retract("RuleD");
} We add the facts into our datacontext, and execute Flags := &Flags{}
Fact := &Fact { Name: "Lucy" }
dataContext := ast.NewDataContext()
err := dataContext.Add("Flags", Flags)
err := dataContext.Add("Fact", Fact)
...
...
eng1 := &engine.GruleEngine{}
err := eng1.Execute(dataContext, kb) When the rule execution by the engine is finished, Then your golang code take over what to do what every you want with the fact. if Flags.Fd {
// Notify the user that they are Suberb !!
fmt.Println("Superb")
}
if Flags.Fc {
// Notify the user that they are Awesome !!
fmt.Println("Awesome")
}
if Flags.Fa {
// Notify the user that they are Cool !!
fmt.Println("Cool")
}
if Flags.Fb {
// Notify the user that they are Great !!
fmt.Println("Great")
} I hope you understand. |
Thank you so much, I understand your approach now. I missed the usage of I'm storing my rules without these extra facts/flags and Retract and retrieve them from an outside source. I wonder if there's a programatic way of adding these expressions (rule assignment and retract) to the rule right before execution and keep the original ones clean and not confusing. I'll dig into the expressions methods but if you guys know how already I'll appreciate it if you could point me to the right direction. Thank you again for all the help already. |
Im happy that you get it. Thats what people on Jboss and Martin Folwer mean by "Rule Engine tell you what to do, but not how to do it". The rule engine is the one to check and validating things, applying some values and hints. But in the end, your code is the one who going to do it, even though, with grule and drools the engine are some how capable of doing it (can call function to do the heavy lifting), but its not advised. Many rule engine only implement the "When" part. Grule and Drools also implement the "Then" part. In real business case, according to some set of Facts, Rule Engine would specify tax value, discounts, amount of chemical substance, estimating things and decide some final values. But thats about it. In the end, your code would take the values produced by rule engine and apply them to real operation. To send notification, to save into database, or to turn the steering wheel left or right. |
@newm4n in this case, how would you handle different saliences? E.g. salience RuleA == RuleB == RuleC == 10, RuleD == 1. I expect it should flag A,B,C but not D |
Hi, I'm a bit confused or lost with this scenario, wonder if you could guide me: Imagine I have 20 rules. And with a given fact, 3 of them pass. The conflict set chooses the highest priority out of those 3. However I need all 3 to be executed (to run the action or then clause).
Use case: I have a triggers/automations system that one trigger (an event like
page created
) could dispatch multiple actions (if the rules or conditions are met). Suppose that the user have created 2 automations (each automation consists of a trigger + GRL that has the action as a fact method) that their associated rules both pass for a given page creation event/trigger. One trigger/automation will send an email (one action or fact method), another will send a notification (another).Couldn't find a way to achieve this. Is there a better way to do this or am I missing something?
The text was updated successfully, but these errors were encountered: