I believe this problem is fixed in trunk already. Would you please try
your own use case, just in case?
Thanks,
Edson
2010/2/8 heldeen <heldeen(a)overstock.com>
Hello,
Using Drools 5.1.0.M1.
I am running into a blocking problem when I concurrently try to update a
fact in my knowledge session, which is fireUntilHalt() in its own thread,
from another thread, an updator thread. I know that only these 2 threads
are
ever accessing each knowledge session.
Has anyone else run into this problem?
I am including the relavant details and can provide a working example if
need be. The block happens randomly anywhere from 20 - 1000's of sessions.
I consistantly get this stack trace from the blocked thread:
org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1540)
org.drools.common.AbstractWorkingMemory.update(AbstractWorkingMemory.java:1529)
org.drools.common.AbstractWorkingMemory.update(AbstractWorkingMemory.java:1403)
org.drools.impl.StatefulKnowledgeSessionImpl.update(StatefulKnowledgeSessionImpl.java:248)
...
I have a simple drools knowledge base that is a basic rule flow [Start ->
Rule Flow Group -> Event Wait -> Rule Flow Group -> End]
I build a knowledge base like this:
KnowledgeBaseConfiguration knowledgeBaseConfiguration =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
knowledgeBaseConfiguration.setOption(AssertBehaviorOption.EQUALITY);
knowledgeBaseConfiguration.setOption(MBeansOption.ENABLED);
KnowledgeBase knowledgeBase =
KnowledgeBaseFactory.newKnowledgeBase(knowledgeBaseConfiguration);
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource(CHANGE_SET_XML,
getClass()), ResourceType.CHANGE_SET);
if (kbuilder.hasErrors()) {
throw new IllegalArgumentException("Unable to build knowledge");
}
knowledgeBase.addKnowledgePackages(kbuilder.getKnowledgePackages());
My basic test fact is:
public class Fact() {
String name;
boolean isReady;
//getters and setters
}
I have a fixed thread pool (Sun's ExecutorService.newFixedThreadPool() with
20 threads). Each session is submitted from a for loop of 0 to 100000 where
it generates a simple fact with Fact.name = "fact"+i and Fact.isReady =
false, then puts it in an array like so:
final Object[] facts...
fixedPoolExecutor.submit(new Runnable() {
@Override
public void run() {
StatefulKnowledgeSession knowledgeSession = null;
try {
knowledgeSession = knowledgeBase.newStatefulKnowledgeSession();
//put it in a ConcurrentHashMap keyed by session id.
...
for (Object fact : facts) {
knowledgeSession.insert(fact);
}
//add session completion halt event - omiting other unused methods
knowledgeSession.addEventListener(new ProcessEventListener() {
@Override
public void afterProcessCompleted(ProcessCompletedEvent event) {
knowledgeSession.halt();
}
});
knowledgeSession.startProcess(PROCESS_ID);
knowledgeSession.fireUntilHalt();
} finally {
if (knowledgeSession != null) {
knowledgeSession.dispose();
}
}
});
I have a single thread executor (Sun's
ExecutorService.newSingleThreadExecutor()) that is used to update these
sessions (basically set the Fact.isReady from false to true for the
EventWait in my rule flow):
final int sessionId...
final Object[] facts...
singleThreadExecutor.submit(new Runnable() {
@Override
public void run() {
StatefulKnowledgeSession knowledgeSession = null;
try {
knowledgeSession = ... from ConcurrentHashMap based on sessionId
FactHandle factHandle = knowledgeSession.getFactHandle(fact);
if (null != factHandle) {
knowledgeSession.update(factHandle, fact);//This is where it blocks
and never returns
} else {
knowledgeSession.insert(fact);
}
});
-Heath
--
View this message in context:
http://n3.nabble.com/StatefulKnowledgeSession-synchronization-problem-tp1...
Sent from the Drools - User mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users