I also think that the approach proposed by Greg of having a Message fact<br>type and various Segment fact types would let you write efficient and <br>maintainable rules. (The extreme splitting into Field facts has several<br>
drawbacks, as has been pointed out, and also: 'value' is always a string,<br>so you lose type checking.) One thing I could not see is the effect of<br>the structural layer of transactions. And another one: are there several<br>
(sub)types of Segment? If so, it will be possible of writing rules against<br>(abstract) base types, e.g.<br><br>abstract class Segment<br>class DebitSeg extends Segment<br>class CreditSeg extends Segment<br><br>rule notPositive<br>
when<br> $s : Segment( amount <= 0 )<br>then<br> weird( $s );<br><br>Also, Segment subtypes might implement interfaces, and its<br>also possible to use them as fact names in patterns.<br><br>-W<br><br><br><div class="gmail_quote">
On Thu, May 28, 2009 at 2:17 AM, David Zeigler <span dir="ltr"><<a href="mailto:dzeigler@gmail.com">dzeigler@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br>
I could use some experienced guidance. I'm in the process of<br>
evaluating Drools for use of using in a real-time transactional<br>
environment to process about 3000 messages/second. I realize a lot of<br>
this depends on the type and quantity of rules, hardware, etc. I'm<br>
curious what steps others have taken to improve performance and if<br>
there are any recommendations for my case detailed below.<br>
<br>
A few specific questions I have are:<br>
- Should each field in a message be a fact? (more info on my message<br>
below) What fact granularity have you settled on in your usage and<br>
why?<br>
- Does the order of the conditions in a rule affect performance, the<br>
execution order, or the structure of the Rete network?<br>
- Does the order the facts are inserted into a stateless session (as<br>
a list via the CommandFactory.newInsertElements) affect performance at<br>
all?<br>
<br>
The message is an EDI format and will typically have anywhere from 80<br>
to 200 fields, potentially more. The message is divided into<br>
transactions, then segments, then fields. We have an object model<br>
that represents the message. We're using a stateless session and most<br>
of the rules will modify fields or add fields and segments based on<br>
the values of other fields. Currently, I flatten the object model<br>
into a List containing the message, transactions, segments, and each<br>
field, and then insert the list into the stateless session and fire.<br>
I'm avoiding sequential mode for now until we have a better idea of<br>
our requirements.<br>
<br>
Here's a simplified example of what I'm doing now (using json-esque<br>
syntax instead of the EDI format).<br>
message {<br>
segment {<br>
SG:header<br>
A0:agents<br>
}<br>
segment {<br>
SG:agent<br>
A1:000<br>
A2:JAMES<br>
A3:BOND<br>
}<br>
segment {<br>
SG:agent<br>
A1:86<br>
A2:MAXWELL<br>
A3:SMART<br>
}<br>
}<br>
<br>
Each field has an id and a value. For this message, I would insert 14<br>
facts: the message object, 3 segments objects, and 10 field objects.<br>
<br>
rule "set James Bond's A1 to 007"<br>
when<br>
$a1 : Field(id == "A1", value != "007")<br>
Field(id == "A2", value == "JAMES")<br>
Field(id == "A3", value == "BOND")<br>
then<br>
$a1.setValue("007");<br>
update($a1);<br>
end<br>
<br>
A relatively more complicated, but typical rule would be "set James<br>
Bond's A1 to 007 iff he's the second agent in the message and one of<br>
the other agents' first names does not contain AUSTIN and an agency<br>
segment exists"<br>
<br>
The above example assumes each segment and field is a fact and I think<br>
it's a clean and flexible approach, but I'm concerned about the<br>
overhead of inserting potentially 250 facts for each message. The<br>
only other alternatives I can think of seem to have their own set of<br>
problems:<br>
1. limit the fields that rules can be written against to a limited<br>
subset, which may not be feasible depending on how the requirements<br>
evolve, and only assert those as facts. Doing this seems to double<br>
the number of transactions per second in my nonscientific benchmark.<br>
2. insert the Message object as a single fact and then write a slew of<br>
accessor methods in that object to get at all possible fields in the<br>
tree: getA1FromSecondAgentSegmentInFirstTransaction(). This seems<br>
like it might perform well, but could be very messy.<br>
3. provide an api in the message object model to find various<br>
occurrences of fields in the messages, then use eval() in the rule.<br>
like eval(msg.findSegment("agent", secondOccurrence).getField("A1")).<br>
I've read that would be less efficient once the ruleset grows.<br>
<br>
I'm sure many of you have dealt with this type scenario before, what<br>
did you determine the best approach to be?<br>
<br>
Thanks,<br>
David<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</blockquote></div><br>