Details
-
Bug
-
Resolution: Done
-
Major
-
4.0.7
-
None
Description
Scenario:
- We are using Drools in a MT app with a shared rulebase and one WM per thread.
- We are using MVEL expressions to dynamically calculate salience from matched facts.
When runniing mutlithreaded, we could observe that expression would sometimes (1 in 500 times in our case) pick up the wrong salience value.
Looking at the source of MVELSalienceExpression.getValue() reveals that the method sets the WM and then evaluates the MVEL expression.
I assume that the MVELSalienceExpression is part of the rulebase and thus shared accross WMs. If this is true this is not thread-safe and may lead to the observed behaviour.
Adding a simple synchronized fixes the problem in our case:
public synchronized int getValue(final Tuple tuple, final WorkingMemory workingMemory) { this.factory.setContext(tuple, null, null, workingMemory, null); return ((Number) MVEL.executeExpression(this.expr, this.factory)).intValue(); }
However this may reduce overall concurrency in the application. A better solution might be to increase locality, ie having a "thread local" factory.