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: &#39;value&#39; 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 &lt;= 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">&lt;<a href="mailto:dzeigler@gmail.com">dzeigler@gmail.com</a>&gt;</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&#39;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&#39;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&#39;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&#39;m avoiding sequential mode for now until we have a better idea of<br>
our requirements.<br>
<br>
Here&#39;s a simplified example of what I&#39;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 &quot;set James Bond&#39;s A1 to 007&quot;<br>
when<br>
  $a1 : Field(id == &quot;A1&quot;,  value != &quot;007&quot;)<br>
  Field(id == &quot;A2&quot;,  value == &quot;JAMES&quot;)<br>
  Field(id == &quot;A3&quot;,  value == &quot;BOND&quot;)<br>
then<br>
  $a1.setValue(&quot;007&quot;);<br>
  update($a1);<br>
end<br>
<br>
A relatively more complicated, but typical rule would be &quot;set James<br>
Bond&#39;s A1 to 007 iff he&#39;s the second agent in the message and one of<br>
the other agents&#39; first names does not contain AUSTIN and an agency<br>
segment exists&quot;<br>
<br>
The above example assumes each segment and field is a fact and I think<br>
it&#39;s a clean and flexible approach, but I&#39;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(&quot;agent&quot;, secondOccurrence).getField(&quot;A1&quot;)).<br>
I&#39;ve read that would be less efficient once the ruleset grows.<br>
<br>
I&#39;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>