Multiple threading
by Apache
Hey,
I am trying to get multiple threads to insert events and run rules against the union of events inserted ( an as soon as they are inserted, a timer drools thread kicking of fireallrules() is not an option because that would introduce a delay ) and wanted some opinion on the following:
1. Stateless session is basically a wrapper around statefulsession and since per doc statefulsession is not threadsafe is it safe to assume 2 threads cannot insert and run fireallrules to compare against a union of objects inserted by multiple threads without some synchronication on event insertion and ESP fireallrulesrules ? ( would the answer still hold despite a drools-camel endpoint reading and storing exchanges from multiple threads ? )
2. If in the above point we simplify the case where the rule uses the "from" keyword and reads from a cache or a Db ( is reading from
A cache supported out of the box ? ) then will drools bhaviour will be bound by the thread which invokes fireallrules() ?
12 years, 9 months
MVEL strict-mode vs. performance
by womuji
Hi,
We are upgrading from Drools 5.1 to 5.3 to improve the performance, but we
are hoping to keep our drl files intact. We were trying to use the old drl
files by setting "drools.dialect.mvel.strict=false", but somehow with this
setting we still got " unable to resolve method using strict-mode .." error
from time to time.
I'm wondering if there is any correlation between this strict-mode and the
performance gain, if in order to achieve the performance gain, we have to
set the strict-mode to true, then we will make changes to our drl files,
instead of spending time to figure out why the effect of
"drools.dialect.mvel.strict=false" is sporadic.
Thanks.
--
View this message in context: http://drools.46999.n3.nabble.com/MVEL-strict-mode-vs-performance-tp37418...
Sent from the Drools: User forum mailing list archive at Nabble.com.
12 years, 9 months
Re: [rules-users] rules-users Digest, Vol 63, Issue 60
by Shur, Bob
I don't understand either of these answers. All of the facts are in a list of facts passed into ksession.execute, like this:
final StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
List<Object> facts = createPosts();
if (facts.size() == 0) break;
long t0 = System.currentTimeMillis()/100;
ksession.execute(facts);
long t1 = System.currentTimeMillis()/100;
System.out.println("Elapsed time: " + (t1 - t0));
There are no more facts getting created during rules processing. The whole drl file is:
rule "collect"
when
$a : ArrayList(size > 0) from collect(Post());
then
System.out.println("Number of posts: " + $a.size());
System.out.println("DONE");
end
Why is the collect happening more than once? Actually I don't think it is, else I would be seeing more than one printout.
I agree that I could probably find a way to do without the list, but I would still like to understand why this is n-squared. I was actually planning to explore the performance of various ways to compute the minimum of a large number of objects. I was surprised to find that I was already up to n-squared just creating the list.
> ------------------------------
>
> Message: 3
> Date: Mon, 13 Feb 2012 20:59:20 +0100
> From: Wolfgang Laun <wolfgang.laun(a)gmail.com>
> Subject: Re: [rules-users] Performance of collect seems to be
> n-squared
> To: Rules Users List <rules-users(a)lists.jboss.org>
> Message-ID:
> <CANaj1LeAnD-
> kYngQqTzo1XoOh4V8tnqo5A+9CkVR6xPmK4gxMA(a)mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> Repeatedly creating this ArrayList is bound to be O(n2).
>
> Why do you want the Post facts as a List? There may be better ways for
> achieving your goal.
>
> -W
>
>
> On 13 February 2012 20:49, Shur, Bob <robert.shur(a)hp.com> wrote:
>
> > I have a simple class Post { int id; ... }. I insert some number of
> them
> > as facts and then call ksession.execute(facts);
> >
> > The whole drl file (except for package and import statements) is:
> >
> > rule "collect"
> > when
> > $a : ArrayList(size > 0) from collect(Post());
> > then
> > System.out.println("Number of posts: " + $a.size());
> > System.out.println("DONE");
> > end
> >
> > The time it takes to run is n-squared in the number of posts. For
> 4000,
> > 8000, 16000, 32000, 64000 posts the time is (in 1/10 seconds):
> >
> > 4, 14, 56, 220, 852
> >
> > Is this expected? Is there a better way for me to do the collect?
> >
> >
> > _______________________________________________
> > rules-users mailing list
> > rules-users(a)lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
> >
>
12 years, 9 months
Performance of collect seems to be n-squared
by Shur, Bob
I have a simple class Post { int id; ... }. I insert some number of them as facts and then call ksession.execute(facts);
The whole drl file (except for package and import statements) is:
rule "collect"
when
$a : ArrayList(size > 0) from collect(Post());
then
System.out.println("Number of posts: " + $a.size());
System.out.println("DONE");
end
The time it takes to run is n-squared in the number of posts. For 4000, 8000, 16000, 32000, 64000 posts the time is (in 1/10 seconds):
4, 14, 56, 220, 852
Is this expected? Is there a better way for me to do the collect?
12 years, 9 months
Re: [rules-users] Error running Drools 5.0 HelloWorldExample on WebSphere 6.1
by Blythe, Marshall
A quick follow-up: this error occurs only when I have rules using the MVEL dialect. I rewrote the MVEL rule in the HelloWorld.drl to use the Java dialect, and now the problem is gone. I may need to raise this issue on the MVEL mailing list instead.
----------------------------------------- This e-mail and any attachments may contain CONFIDENTIAL information, including PROTECTED HEALTH INFORMATION. If you are not the intended recipient, any use or disclosure of this information is STRICTLY PROHIBITED; you are requested to delete this e-mail and any attachments, notify the sender immediately, and notify the LabCorp Privacy Officer at privacyofficer(a)labcorp.com or call (877) 23-HIPAA.
12 years, 9 months
Performance scaling with fact insertion
by St. Lawrence, Zachary
I was running some performance analysis on my rules so I could tune in hopes of scaling up from hundreds of thousands of datapoints to millions of entries and noticed some alarming performance scaling issues when rules are firing and inserting dependent objects. At first I thought it was one of my more complex rules but when I broke down my examples to the simplest possible test cases I found that the central problem was that performance was not linear with number of facts inserted -- it was polynominal (roughly n^2.5).
My simplest test example was basically each fact inserted initially would trigger a new logical relationship fact to be inserted. No fancy logic. Also it could not trigger itself recursively. I tried three approaches : logical inserts of new facts, manual inserts/retraction, and update of the current fact with new data.
Updates on current fact were roughly linear assuming I prevented re-firing.
Manual Inserts and retracts scaled with O(n^2.5)
LogicalInserts were O(n^3)
The documentation suggest insertion of dependent facts to simplify logic. But when dealing with tens of thousands of events triggering it did not scale sufficiently. Can anyone tell me what I may have done wrong? I have included rules and data below.
This was on 5.3 using fireAllRules. The time measured was rule execution only and excluded times due to my testing framework.
// SIMPLIFIED RULES FILE
declare DataPoint
anomaly : boolean
entityId : String
average : double
predict : double
predictDev : double
timestamp : long
end
declare AnomalyFact
entityId : String
anomalyType : AnomalyType
ruleName : String
timestamp : long
end
rule "Traffic Below 4 Deviations"
no-loop
when
$datapoint : DataPoint (
anomaly==false,
average < (predict - (predictDev * 4))
)
then
// update self only. This line was always active.
modify($datapoint) {setAnomaly(true)};
// on logicalInsert test I commented in the following line
// insertLogical( new AnomalyFact ( $datapoint.getEntityId(), AnomalyEnum.LOW, drools.getRule().getName(), $datapoint.getTimestamp()));
// on insert test I commented in the following line and added another rule to retract any anomaly with no datapoint
// insert( new AnomalyFact ( $datapoint.getEntityId(), AnomalyEnum.LOW, drools.getRule().getName(), $datapoint.getTimestamp()));
end
/* TEST RESULT CONTAINED BELOW
All data inserted triggered the rule. I was load testing for worst case behavior.
logicalInsert
n run1 run2 run3
5000 1293 1232 1767
10000 9458 8210 10079
15000 24389 31050 24311
30000 134936
manual insert/retract
n run1 run2 run3
5000 1137 1094 1169
10000 8090 5862 5616
15000 16741 16728 15874
30000 76034
update on current object only
n run1 run2 run3
5000 417 444 413
10000 600
15000 712 697 688
30000 999 970 1041 1016 1163
60000 1420
100000 1930
Thanks for any help!
*/
12 years, 9 months
(no subject)
by Alberto R. Galdo
According to the documentation:
"Rule constraints do not have direct access to variables defined inside the
> process.
> It is however possible to refer to the current process instance inside a
> rule constraint,
> by adding the process instance to the Working Memory and matching for the
> process instance in your rule constraint.
> We have added special logic to make sure that a variable processInstance
> of type WorkflowProcessInstance
> will only match to the current process instance and not to other process
> instances in the Working Memory.
> Note that you are however responsible yourself to insert the process
> instance into the session and,
> possibly, to update it, for example, using Java code or an on-entry or
> on-exit or explicit action in your process.
> The following example of a rule constraint will search for a person with
> the same name as the value stored in the variable "name" of the process:"
>
This however does not seem to be true.
The first rule is to receive a stream of objects of type MyObject.
This rule starts an associated process.
The second rule will be called by the process (from bpmn).
Within the process there a task that invokes an an asynchronous service, ie,
an implementation of WorkItemHandler that contains a Thread that will set
call
manager.completeWorkItem(workItemId,results);
when 30s have passed).
With this setup we can observe what happens when 2 MyObject instances come
into the first rule separated by a short period of time (say 5 seconds).
When the first object comes in a process is created and started (with
process id=1)
The process passes from the start node to the callMyTask node, which
invokes the slow WorkItemHandler references by MyTask
(which we have previously registered into session.getWorkItemManager() ).
Because the WorkItemHandler has a thread that waits 30s before completing
the work item, it just sits there doing nothing (so far everything is ok)
and allows the engine to process other events.
5 seconds later we insert another MyObject into the stream.
The first rule gets fired and created another process (with process id=2).
The process passes from the start node to the callMyTask node, which invoke
our slow service.
We have thus two processes running in parallel.
When the first callMyTask node completes, the next node completeTask is
invoked.
The rule "process complete" is matched as it belongs to the rule flow group
"Complete task group".
At this point we observe that the rule is matched twice spitting out:
processInstance.id 2
processInstance.id 1
.
So the rule has matched both process instances that are in working memory
and not just the one (with process id 1)
that called the "process complete" rule.
The rule file
-------------
rule "New case"
when
$myobject : MyObject(processed==false) from entry-point "myobject
stream"
then
ProcessInstance
processInstance=kcontext.getKnowledgeRuntime().createProcessInstance("com.mycompany.process.MyProcess",
parameters);
insert(processInstance);
kcontext.getKnowledgeRuntime().startProcessInstance(processInstance.getId());
modify ($myobject){
setProcessed(true)
}
end
rule "process complete"
ruleflow-group "Complete task group"
no-loop true
when
$processInstance: WorkflowProcessInstance()
then
System.out.println("processInstance.id " +
$processInstance.getId());
end
The BPMN xml
------------
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Definition"
targetNamespace="http://www.jboss.org/drools"
typeLanguage="http://www.java.com/javaTypes"
expressionLanguage="http://www.mvel.org/2.0"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODELBPMN20.xsd"
xmlns:g="http://www.jboss.org/drools/flow/gpd"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:tns="http://www.jboss.org/drools">
<process processType="Private" isExecutable="true"
id="com.mycompany.process.MyProcess" name="my process" >
<!-- process variables -->
<!-- nodes -->
<startEvent id="start" name="StartProcess" />
<task id="callMyTask" name="call my task" tns:taskName="MyTask" >
<ioSpecification>
</ioSpecification>
</task>
<businessRuleTask id="completeTask" name="Complete slow task"
g:ruleFlowGroup="Complete task group" >
</businessRuleTask>
<endEvent id="end" name="EndProcess" />
<!-- connections -->
<sequenceFlow id="start-callMyTask" sourceRef="start"
targetRef="callMyTask" />
<sequenceFlow id="callMyTask-completeTask" sourceRef="callMyTask"
targetRef="completeTask" />
<sequenceFlow id="completeTask-end" sourceRef="completeTask"
targetRef="end" />
</process>
</definitions>
What's wrong with this? Isn't WorkflowProcessInstance() supposed to be
attached to the calling ProcessInstance? Is there another way of getting
the group of rules fire only for the processinstance that called it?
Greets,
12 years, 9 months
How to get the Fact datatypes from the Guvnor
by Veera
Hi All,
Can anybody help to get the Field type(what datatype it is ).
I have declared a Facts in Guvnor 5.3 and i can able to retreive all the
package names & rules names & fact names , now i want to know what is the
datatype of each fact , i don't know which api to use for this.
Can any body help me pelase...
below code to get the all package names & rules names & fact names...:
Collection<KnowledgePackage> kpackages =
_kagent.getKnowledgeBase().getKnowledgePackages();
for(KnowledgePackage kpackage : kpackages)
{
for(org.drools.definition.rule.Rule rule1 :kpackage.getRules())
{
//printing package names & rule names.
String packname= rule1.getPackageName();
String rulename=rule1.getName();
System.out.println("This is : "+packname+" Packages and
RuleName is " +rulename);
//printing Fact names..
Field[] s=kpackage.getClass().getFields();
System.out.println(s.toString());
}
}
Thanks,
Veera
--
View this message in context: http://drools.46999.n3.nabble.com/How-to-get-the-Fact-datatypes-from-the-...
Sent from the Drools: User forum mailing list archive at Nabble.com.
12 years, 9 months