[jboss-jira] [JBoss JIRA] (DROOLS-309) Multiple threads working with traits against same knowledge base hangs
Mario Fusco (JIRA)
jira-events at lists.jboss.org
Tue Oct 29 05:03:03 EDT 2013
[ https://issues.jboss.org/browse/DROOLS-309?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mario Fusco resolved DROOLS-309.
--------------------------------
Fix Version/s: 5.5.1.Final
6.0.0.Final
Resolution: Done
> Multiple threads working with traits against same knowledge base hangs
> ----------------------------------------------------------------------
>
> Key: DROOLS-309
> URL: https://issues.jboss.org/browse/DROOLS-309
> Project: Drools
> Issue Type: Quality Risk
> Security Level: Public(Everyone can see)
> Affects Versions: 5.5.0.Final
> Reporter: James Myers
> Assignee: Mario Fusco
> Fix For: 5.5.1.Final, 6.0.0.Final
>
>
> In our web system, we are creating new StatefulKnowledgeSession per user session and executing a set of rules containing trait donning. This starts to hang (seemingly indefinitely) with following type of stack trace (usually initiated from insert/update):
> {quote}
> java.lang.Thread.State: RUNNABLE
> at org.drools.core.util.TripleStore.getAll(TripleStore.java:188)
> at org.drools.factmodel.traits.TripleBasedStruct.getTriplesForSubject(TripleBasedStruct.java:165)
> at org.drools.factmodel.traits.ThingorgdroolsfactmodeltraitsTraitSession$ItemWrapperProxyWrapper.hashCode(Unknown Source)
> at org.drools.factmodel.traits.TraitProxy.hashCode(TraitProxy.java:110)
> at org.drools.factmodel.traits.ThingorgdroolsfactmodeltraitsTraitSession$ItemWrapperProxy.hashCode(Unknown Source)
> at org.drools.common.DefaultFactHandle.<init>(DefaultFactHandle.java:110)
> at org.drools.common.DefaultFactHandle.<init>(DefaultFactHandle.java:98)
> at org.drools.common.TraitFactHandle.<init>(TraitFactHandle.java:26)
> at org.drools.reteoo.ReteooFactHandleFactory.newFactHandle(ReteooFactHandleFactory.java:80)
> at org.drools.common.AbstractFactHandleFactory.newFactHandle(AbstractFactHandleFactory.java:68)
> at org.drools.common.AbstractFactHandleFactory.newFactHandle(AbstractFactHandleFactory.java:53)
> at org.drools.common.NamedEntryPoint.createHandle(NamedEntryPoint.java:765)
> at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:301)
> at org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:903)
> {quote}
> Here is a unit test for org.drools.factmodel.traits.TraitTest. It's not perfect because it will spawn thread that might never die and may need thread/iteration count increased to fail consistently, but capturing a stack trace a few seconds in should show all threads in "getAll()":
> {code}
> @Traitable
> public static class Item {
> private String id;
> public String getId() {
> return id;
> }
> public void setId(String id) {
> this.id = id;
> }
> }
> public static class TraitRulesThread implements Runnable {
> int threadIndex;
> int numRepetitions;
> StatefulKnowledgeSession ksession;
> public TraitRulesThread(int threadIndex, int numRepetitions, final StatefulKnowledgeSession ksession) {
> this.threadIndex = threadIndex;
> this.numRepetitions = numRepetitions;
> this.ksession = ksession;
> }
> public void run() {
> for (int repetitionIndex = 0; repetitionIndex < numRepetitions; repetitionIndex++) {
> final Item i = new Item();
> i.setId(String.format("testId_%d%d", threadIndex, repetitionIndex));
> ksession.insert(i);
> ksession.fireAllRules();
> }
> }
> }
> @Test
> public void testMultithreadingTraits() throws InterruptedException {
> final String s1 = "package test;\n" +
> "import org.drools.factmodel.traits.TraitTest.Item;\n" +
> "declare Item end\n" +
> "declare trait ItemStyle\n" +
> " id: String\n" +
> " adjustable: boolean\n" +
> "end\n" +
> "rule \"Don ItemStyle\"\n" +
> " no-loop true\n" +
> " when\n" +
> " $p : Item ()\n" +
> " not ItemStyle ( id == $p.id )\n" +
> " then\n" +
> " don($p, ItemStyle.class);\n" +
> "end\n" +
> "rule \"Item Style - Adjustable\"" +
> " no-loop true" +
> " when" +
> " $style : ItemStyle ( !adjustable )" +
> " Item (" +
> " id == $style.id " +
> " )" +
> " then" +
> " modify($style) {" +
> " setAdjustable(true)" +
> " };" +
> "end";
> final KnowledgeBase kbase = getKnowledgeBaseFromString(s1);
> // might need to tweak these numbers. often works with 7-10,100,60, but often fails 15-20,100,60
> int MAX_THREADS = 20;
> int MAX_REPETITIONS = 100;
> int MAX_WAIT_SECONDS = 60;
> final ExecutorService executorService = Executors.newFixedThreadPool(MAX_THREADS);
> for (int threadIndex = 0; threadIndex < MAX_THREADS; threadIndex++) {
> executorService.execute(new TraitRulesThread(threadIndex, MAX_REPETITIONS, kbase.newStatefulKnowledgeSession()));
> }
> executorService.shutdown();
> executorService.awaitTermination(MAX_WAIT_SECONDS, TimeUnit.SECONDS);
> final List<Runnable> queuedTasks = executorService.shutdownNow();
> assertEquals(0, queuedTasks.size());
> assertEquals(true, executorService.isTerminated());
> }
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list