In my application, all threads are blocking during initialization of drools session
java.lang.Thread.State: BLOCKED
at org.drools.reteoo.common.ReteWorkingMemory.initInitialFact(ReteWorkingMemory.java:108)
- waiting to lock <5385ba43> (a java.lang.Integer) owned by "Thead-23" t@42
at org.drools.reteoo.common.ReteWorkingMemory.fireAllRules(ReteWorkingMemory.java:129)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1260)
at org.drools.impl.adapters.StatefulKnowledgeSessionAdapter.fireAllRules(StatefulKnowledgeSessionAdapter.java:72)
java.lang.Thread.State: BLOCKED
at org.drools.reteoo.common.ReteWorkingMemory.initInitialFact(ReteWorkingMemory.java:108)
- waiting to lock <5385ba43> (a java.lang.Integer) owned by "Thead-01" t@42
at org.drools.reteoo.common.ReteWorkingMemory.fireAllRules(ReteWorkingMemory.java:129)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1260)
at org.drools.impl.adapters.StatefulKnowledgeSessionAdapter.fireAllRules(StatefulKnowledgeSessionAdapter.java:72)
The easiest way to replicate the issue is by creating a drools file with the following condition:-
rule "slowWhenCondition" when eval(mySlowCondition(fact)) then end
Create a StatefulSession and fire all the rules from multiple threads. Observe the threads in Blocking state using JVisualVM or Stack Trace.
Upon investigating further I figured that the following code which is invoked during the initialization of ReteWorkingMemory is causing the problem
private final Integer syncLock = 42;
public void initInitialFact() {
if ( initialFactHandle == null ) {
synchronized ( syncLock ) {
if ( initialFactHandle == null ) {
// double check, inside of sync point incase some other thread beat us to it.
initInitialFact(kBase, null);
}
}
}
}
An Integer constant used for locking causes all threads having unrelated rules to block on each other. The most obvious fix is changing the syncLock from Integer constant to Object syncLock = new Object(). Is there any reason why it should not be changed.
I am working on Drools 6.3 Final and using Java 8 on CentOS. Each thread in the application creates its own Stateful Session.
The issue has been resolved by the suggested fix and is now a part of Drools 6.4. More information can be found at the following location https://issues.jboss.org/browse/DROOLS-1046