Nested flow terminating parent flow prematurely
by Tom.E.Murphy@wellsfargo.com
Hi.
I'm struggling with a rule flow that contains another rule flow.
Rule flow 1 - first step is to invoke a sub-process, call it rule flow 2.
Rule flow 2 executes fine, with correct internal branching logic.
Rule flow 2 proceeds to an End object with terminates set to false.
After RF2 completes, I am expecting a return to the parent flow, RF1.
However, entire flow terminates and subsequent RF Groups and or RF's in parent flow are never activated.
Is this a bug or am I specifying something incorrectly?
Using Version 5.0.0.CR1
Code for the two flows is below (excuse the ugly ID's and names - these are generated from our rule repository software):
<!-- TOP / OUTERMOST FLOW: -->
<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://drools.org/drools-5.0/process"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
type="RuleFlow" name="RF6677: R3.09 GAIP" id="29405" package-name="com.wellsfargo.GeneratedRules" version="2" >
<header>
<imports>
<import name="com.wellsfargo.service.provider.hcfg.entity.workingObjects.x2007.PolicySet" />
</imports>
</header>
<nodes>
<start id="1" name="Start" x="105" y="108" width="48" height="48" />
<join id="3" name="EndJoin" x="500" y="500" type="3" />
<end id="4" name="End" x="600" y="600" terminate="false" />
<subProcess id="29403" name="R3.09 GAIP REP 3" x="400" y="400" processId="29403" >
</subProcess>
<ruleSet id="50000580" name="50000580" x="300" y="300" ruleFlowGroup="RF6677_50000580" />
<subProcess id="29364" name="R3.09 GAIP REP 1" x="200" y="200" processId="29364" >
</subProcess>
<split id="150000579" x="458" y="205" width="48" height="48" type="2" >
<constraints>
<constraint toNodeId="50000580" toType="DROOLS_DEFAULT" name="constraint" priority="1" type="rule" dialect="mvel" >PolicySet ( serviceFlowCode == "GAIP" )</constraint>
<constraint toNodeId="3" toType="DROOLS_DEFAULT" name="constraint" priority="1" type="rule" dialect="mvel" >PolicySet ( serviceFlowCode == "Post Rules Processing" )</constraint>
</constraints>
</split>
</nodes>
<connections>
<connection from="29403" to="3" />
<connection from="150000579" to="3" />
<connection from="3" to="4" />
<connection from="50000580" to="29403" />
<connection from="150000579" to="50000580" />
<connection from="1" to="29364" />
<connection from="29364" to="150000579" />
</connections>
</process>
<!-- FIRST INNER FLOW - subProcess id="29403" -->
<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://drools.org/drools-5.0/process"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
type="RuleFlow" name="RF6662: R3.09 GAIP REP 1" id="29364" package-name="com.wellsfargo.GeneratedRules" version="2" >
<header>
<imports>
<import name="com.wellsfargo.service.provider.hcfg.entity.decision.x2007.RiskDecisionResultEnum" />
<import name="com.wellsfargo.service.provider.hcfg.document.loanFile.x2007.TransactionDecisionResults" />
</imports>
</header>
<nodes>
<start id="1" name="Start" x="405" y="12" width="48" height="48" />
<join id="250000560" x="661" y="351" width="48" height="48" type="3" />
<ruleSet id="50000554" name="50000554" x="390" y="109" width="80" height="48" ruleFlowGroup="RF6662_50000554" />
<ruleSet id="50000555" name="50000555" x="388" y="231" width="80" height="48" ruleFlowGroup="RF6662_50000555" />
<end id="3" name="End" x="682" y="754" width="48" height="48" terminate="false" />
<ruleSet id="50000556" name="50000556" x="137" y="349" width="80" height="48" ruleFlowGroup="RF6662_50000556" />
<ruleSet id="50000557" name="50000557" x="137" y="510" width="80" height="48" ruleFlowGroup="RF6662_50000557" />
<ruleSet id="50000558" name="50000558" x="253" y="506" width="80" height="48" ruleFlowGroup="RF6662_50000558" />
<ruleSet id="50000584" name="50000584" x="552" y="501" width="80" height="48" ruleFlowGroup="RF6662_50000584" />
<ruleSet id="50000559" name="50000559" x="403" y="505" width="80" height="48" ruleFlowGroup="RF6662_50000559" />
<split id="150000555" x="404" y="351" width="48" height="48" type="2" >
<constraints>
<constraint toNodeId="250000560" toType="DROOLS_DEFAULT" name="constraint" priority="1" type="rule" dialect="mvel" >TransactionDecisionResults ( riskDecisionResult == RiskDecisionResultEnum.NO_DECISION )</constraint>
<constraint toNodeId="50000556" toType="DROOLS_DEFAULT" name="constraint" priority="1" type="rule" dialect="mvel" >TransactionDecisionResults ( riskDecisionResult != RiskDecisionResultEnum.NO_DECISION )</constraint>
</constraints>
</split>
<ruleSet id="50000560" name="50000560" x="650" y="595" width="80" height="48" ruleFlowGroup="RF6662_50000560" />
</nodes>
<connections>
<connection from="50000584" to="250000560" />
<connection from="150000555" to="250000560" />
<connection from="1" to="50000554" />
<connection from="50000554" to="50000555" />
<connection from="50000560" to="3" />
<connection from="150000555" to="50000556" />
<connection from="50000556" to="50000557" />
<connection from="50000557" to="50000558" />
<connection from="50000559" to="50000584" />
<connection from="50000558" to="50000559" />
<connection from="50000555" to="150000555" />
<connection from="250000560" to="50000560" />
</connections>
</process>
Tom Murphy
Business Process Consultant
Wells Fargo HCFG - CORE Deal Decisioning Platform
800 S. Jordan Creek Parkway | West Des Moines, IA 50266
MAC: X2301-01B
Office: 515 324 4853 | Mobile: 941 320 8014
This message may contain confidential and/or privileged information. If you are not the addressee or authorized to receive this for the addressee, you must not use, copy, disclose, or take any action based on this message or any information herein. If you have received this message in error, please advise the sender immediately by reply e-mail and delete this message. Thank you for your cooperation.
15 years, 6 months
Date questions
by Armaghan Mahmud
Hi guys,
I'm looking to do the following and I was wondering how to use Date objects
in Drools. This is what I currently have:
rule "Difference between end and start time is less than a very small
(threshold) value."
*salience* 100
when
*obs*: ObsClass((endTime - startTime) < someVerySmallValue)
then
System.out.*println*("Difference between end and start time is less than
a very small (threshold) value.");
End
rule "Check if user defined time frame falls between startTime and endTime
variables"
*salience* 100
when
*obs*: ObsClass((endTime - userDefinedTime) > 0 && (userDefinedTime -
startTime) > 0)
then
System.out.println("Check if user defined time frame falls between
startTime and endTime variables")
end
The problem I'm having with dates is in comparing them. The mathematical
portion of the rules above kind of explain what I want to do but I doubt
I'll be able to achieve my goals. Any help would be greatly appreciated.
Thanks in advance,
Armaghan
15 years, 6 months
fact granularity, performance, and other questions
by David Zeigler
Hi,
I could use some experienced guidance. I'm in the process of
evaluating Drools for use of using in a real-time transactional
environment to process about 3000 messages/second. I realize a lot of
this depends on the type and quantity of rules, hardware, etc. I'm
curious what steps others have taken to improve performance and if
there are any recommendations for my case detailed below.
A few specific questions I have are:
- Should each field in a message be a fact? (more info on my message
below) What fact granularity have you settled on in your usage and
why?
- Does the order of the conditions in a rule affect performance, the
execution order, or the structure of the Rete network?
- Does the order the facts are inserted into a stateless session (as
a list via the CommandFactory.newInsertElements) affect performance at
all?
The message is an EDI format and will typically have anywhere from 80
to 200 fields, potentially more. The message is divided into
transactions, then segments, then fields. We have an object model
that represents the message. We're using a stateless session and most
of the rules will modify fields or add fields and segments based on
the values of other fields. Currently, I flatten the object model
into a List containing the message, transactions, segments, and each
field, and then insert the list into the stateless session and fire.
I'm avoiding sequential mode for now until we have a better idea of
our requirements.
Here's a simplified example of what I'm doing now (using json-esque
syntax instead of the EDI format).
message {
segment {
SG:header
A0:agents
}
segment {
SG:agent
A1:000
A2:JAMES
A3:BOND
}
segment {
SG:agent
A1:86
A2:MAXWELL
A3:SMART
}
}
Each field has an id and a value. For this message, I would insert 14
facts: the message object, 3 segments objects, and 10 field objects.
rule "set James Bond's A1 to 007"
when
$a1 : Field(id == "A1", value != "007")
Field(id == "A2", value == "JAMES")
Field(id == "A3", value == "BOND")
then
$a1.setValue("007");
update($a1);
end
A relatively more complicated, but typical rule would be "set James
Bond's A1 to 007 iff he's the second agent in the message and one of
the other agents' first names does not contain AUSTIN and an agency
segment exists"
The above example assumes each segment and field is a fact and I think
it's a clean and flexible approach, but I'm concerned about the
overhead of inserting potentially 250 facts for each message. The
only other alternatives I can think of seem to have their own set of
problems:
1. limit the fields that rules can be written against to a limited
subset, which may not be feasible depending on how the requirements
evolve, and only assert those as facts. Doing this seems to double
the number of transactions per second in my nonscientific benchmark.
2. insert the Message object as a single fact and then write a slew of
accessor methods in that object to get at all possible fields in the
tree: getA1FromSecondAgentSegmentInFirstTransaction(). This seems
like it might perform well, but could be very messy.
3. provide an api in the message object model to find various
occurrences of fields in the messages, then use eval() in the rule.
like eval(msg.findSegment("agent", secondOccurrence).getField("A1")).
I've read that would be less efficient once the ruleset grows.
I'm sure many of you have dealt with this type scenario before, what
did you determine the best approach to be?
Thanks,
David
15 years, 6 months
keeping running stats
by Chris Richmond
Hello,
I have modified the stockTicker fusion example to keep some running stats,
you can see from the rule snippet below that it injects a stats object based
on the symbol then matches them as updates come in later. You can see for
now I am just updating the running counts and outputting the readings count
on each stock tick and this works fine.
What I would like to do however is only have the running averages,stats
object reflect stock ticks that are still in memory..essentiall only stock
tick items that have not expired. As it is now the count just keeps growing
and growing, I want the count to only reflect the stock ticks within the
expiration time in the past for stock ticks, but I cannot figure out how to
make this happen? Could anyone give me a pointer on how to do this? How
to make the stats object only reflect those stock ticks that have not
expired? I do not know the strategy for this.
Thanks,
Chris
# tells the engine that a StockTick instance will assume the
# role (semantics) of events and that the default retention
# policy will be 2 minutes
declare StockTick
@role( event )
@expires( 1m )
end
# One can even declare helper facts to make rules easier and
# simpler to write and maintain
declare Statistics
symbol : String @key()
average : double
readings : int
total : double
end
rule "Setup statistics"
when
$c : Company( $s : symbol )
not( Statistics( symbol == $s ) )
then
Statistics s = new Statistics();
s.symbol = $s;
s.readings = s.readings + 1;
insert( s );
end
# a simple rule to show that it is possible to join
# events from an entry-point (stream) with facts
# present in the working memory
rule "Update stock stats"
agenda-group "evaluation"
lock-on-active
when
$cp : Company( $sb : symbol )
$st : StockTick( symbol == $sb, $pr : price ) from entry-point
"StockTick stream"
$stats : Statistics( symbol == $sb )
then
modify( $stats ) { readings = readings + 1};
System.err.println($stats.symbol + "readings: " + $stats.readings);
// This shows an update on working memory facts with data from joined
events
//modify( $cp ) { currentPrice = $pr }
// Although events are considered immutable, a common pattern is to use
a class
// to represent an event and enrich that event instance with data
derived from other facts/events.
// Bellow we "enrich" the event instance with the percentual change in
the price,
// based on the previous price
//modify( $st ) { delta = $cp.delta }
//modify( $st ) { readings = 5 }
//System.out.println($st.delta)
end
15 years, 6 months
Re: [rules-users] fact granularity, performance, and other questions
by Greg Barton
To address some points in order:
Yes, having each field in a message as a fact is the most straightforward. The catch is that the rejoining conditions should be as fast as possible. I'm thinking this structure would be best:
class Message {
...message level properties...
}
class Segment {
public Message message;
public int position;
...Segment level properties
}
Then the rules would be like this:
when
m: Message(...foo...);
s0: Segment(position == 0, message == m, ...bar...)
s1: Segment(position == 1, message == m, ...bas...)
then
...
end
That's about as fast as you'll get with this setup, I figure. And you're right, it is important to list the conditions in a certain order: with the "position == n" condition before the "message == m" condition, MANY Segments in working memory are eliminated from consideration before getting to the more expensive cross object join. (Even though the cross object condition is about as cheap as you can get, a straight == check.)
I'm not sure about the answer to the fact insertion order question vis a vis performance in a stateless session. My guess is no effect, but probably a question for the devs. (Or a bit 'o' experimentation.)
It would be nice if your item #2 could be accomplished with a class property that's a multidimensional String array, though it throws an array out of bounds exception if you try testing for an array position that's too high. Another way (which I think is what you suggest below) would be to have a one time generated class to with the following structure:
class Fact {
String[][][] facts;
public String geta0s0t0() {
if(facts.length >=1 && facts[0].length >= 1 facts[0][0].length >= 0) {
return facts[0][0][0];
} else {
return "";
}
}
}
Initialize each one with a String[][][] and you're on your way. This would absolutely be faster than the first method above, probably by several orders of magnitude.
Another approach would be to see how hard it would be to alter mvel so it evaluates the array[out_of_bounds_index] expressions to false instead of throwing an exception. Maybe for the long term...
--- On Wed, 5/27/09, David Zeigler <dzeigler(a)gmail.com> wrote:
> From: David Zeigler <dzeigler(a)gmail.com>
> Subject: [rules-users] fact granularity, performance, and other questions
> To: "Rules Users List" <rules-users(a)lists.jboss.org>
> Date: Wednesday, May 27, 2009, 7:17 PM
> Hi,
> I could use some experienced guidance. I'm in the
> process of
> evaluating Drools for use of using in a real-time
> transactional
> environment to process about 3000 messages/second. I
> realize a lot of
> this depends on the type and quantity of rules, hardware,
> etc. I'm
> curious what steps others have taken to improve performance
> and if
> there are any recommendations for my case detailed below.
>
> A few specific questions I have are:
> - Should each field in a message be a fact? (more info on
> my message
> below) What fact granularity have you settled on in
> your usage and
> why?
> - Does the order of the conditions in a rule affect
> performance, the
> execution order, or the structure of the Rete network?
> - Does the order the facts are inserted into a stateless
> session (as
> a list via the CommandFactory.newInsertElements) affect
> performance at
> all?
>
> The message is an EDI format and will typically have
> anywhere from 80
> to 200 fields, potentially more. The message is
> divided into
> transactions, then segments, then fields. We have an
> object model
> that represents the message. We're using a stateless
> session and most
> of the rules will modify fields or add fields and segments
> based on
> the values of other fields. Currently, I flatten the
> object model
> into a List containing the message, transactions, segments,
> and each
> field, and then insert the list into the stateless session
> and fire.
> I'm avoiding sequential mode for now until we have a better
> idea of
> our requirements.
>
> Here's a simplified example of what I'm doing now (using
> json-esque
> syntax instead of the EDI format).
> message {
> segment {
> SG:header
> A0:agents
> }
> segment {
> SG:agent
> A1:000
> A2:JAMES
> A3:BOND
> }
> segment {
> SG:agent
> A1:86
> A2:MAXWELL
> A3:SMART
> }
> }
>
> Each field has an id and a value. For this message, I
> would insert 14
> facts: the message object, 3 segments objects, and 10
> field objects.
>
> rule "set James Bond's A1 to 007"
> when
> $a1 : Field(id == "A1", value != "007")
> Field(id == "A2", value == "JAMES")
> Field(id == "A3", value == "BOND")
> then
> $a1.setValue("007");
> update($a1);
> end
>
> A relatively more complicated, but typical rule would be
> "set James
> Bond's A1 to 007 iff he's the second agent in the message
> and one of
> the other agents' first names does not contain AUSTIN and
> an agency
> segment exists"
>
> The above example assumes each segment and field is a fact
> and I think
> it's a clean and flexible approach, but I'm concerned about
> the
> overhead of inserting potentially 250 facts for each
> message. The
> only other alternatives I can think of seem to have their
> own set of
> problems:
> 1. limit the fields that rules can be written against to a
> limited
> subset, which may not be feasible depending on how the
> requirements
> evolve, and only assert those as facts. Doing this
> seems to double
> the number of transactions per second in my nonscientific
> benchmark.
> 2. insert the Message object as a single fact and then
> write a slew of
> accessor methods in that object to get at all possible
> fields in the
> tree:
> getA1FromSecondAgentSegmentInFirstTransaction(). This
> seems
> like it might perform well, but could be very messy.
> 3. provide an api in the message object model to find
> various
> occurrences of fields in the messages, then use eval() in
> the rule.
> like eval(msg.findSegment("agent",
> secondOccurrence).getField("A1")).
> I've read that would be less efficient once the ruleset
> grows.
>
> I'm sure many of you have dealt with this type scenario
> before, what
> did you determine the best approach to be?
>
> Thanks,
> David
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
15 years, 6 months
moving average rule
by Chris Richmond
Hello,
I am trying to write a rule for a moving average over values over the last
minute using fusion. In general I can't seem to locate a detailed resource
for authoring syntax for these types of rules or rules in general, but
specifically, I tried to modify something from the fusion documentation for
my purposes using the StockTicker fusion sample. Here is the rule entry I
aded to the broker.drl:
rule "Alert when moving average goes below 50"
when
Number( doubleValue > 127 ) from accumulate(
StockTick( symbol == "ORCL", $price: price ) over window:time( 1m ),
average( $price ) )
then
System.out.println("moving average has gone beyone moving average");
End
I basically want to be alerted any time the moving average for ORCL moves
above 127 (or whatever criteria I set.I picked that based on the sample data
the sample fusion project uses), but it doesn't seem to be working.
I guess if I could locate the definitave samples or guide for authoring
these types of rules I could use that, but it's very difficult to piece
together how to author rules utilizing fusion features based on isolated
snippets from the fusion guide.
Can anyone point me to some reasources for learning rule authoring,
especially for taking advantage of the fusion features.
Thanks,
Chris
15 years, 6 months
Rules Effective Date
by Srinivas Doddi
Hi Nicoloas
Thank you for pointing it out. I went through it previously, but
somehow missed that point.
Hi Jonathan
I went through Fusion, but couldn't relate how the Events can be related
to the Rules effective dates.
And adding to my initial query,
So, can we modify the attribute "date expires" for an existing rule when
the application is running, and the rules engine knows about it and
expires the rule, without restarting the application? I am talking about
4.0.7 in particular?
Also, I see that Rule names should be unique, so does it mean that we
can't have 2 rules with same name and different effective date ranges?
Sorry for asking these without trying, we are still in the process of
brain storming, and need to know what Rules has to offer. I am still in
the process of setting up Rules on my pc.
Thank you.
SRINI
15 years, 6 months
Rules Effective Date
by Srinivas Doddi
Hi
I am a newbie for Drools and googled for a good time. I would like to
know if Drools 4.0.7 and Drools 5 have anything like an "Effective Date"
concept? We have a requirement for having a rule written by the Business
Analysts and takes effective for a future date, without restarting the
application. Is Rules Engine intelligent enough to pick the rules
depending on effective dates?
Thanks a lot for your help.
SRINI
15 years, 6 months
executing ruleflow with AgendaFilter
by Michal Bali
Hi,
If a rule is not allowed to fire by an AgendaFilter the whole ruleflow
stops.
I've created a small test case (attached). It contains:
- one DRL file with one dummy rule that is in some ruleflow-group.
- one RF file with three nodes ('start', 'ruleflow group' and 'end')
- a program that starts the process, and calls fireAllRules with custom
agenda filter.
Once the program is executed the ruleflow will stop inside the
ruleflow-group. If I remove the agenda filter it works as expected (the
ruleflow finishes).
Tested with Drools 5.0.1.
Is this a bug or am I missing something?
Best regards,
Michal
15 years, 6 months