[
https://issues.jboss.org/browse/DROOLS-1197?page=com.atlassian.jira.plugi...
]
Mario Fusco resolved DROOLS-1197.
---------------------------------
Resolution: Rejected
The problem is caused by the fact that you're (implicitly) using 2 KieContainers with
the same ReleaseId, while that one is supposed to be unique. This is a fixed version of
your test case.
{code}
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.io.KieResources;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static org.junit.Assert.assertEquals;
public class ConcurrencyTest {
KieContainer createContainer(String rule, int id) {
KieServices kieServices = KieServices.Factory.get();
KieResources kieResources = kieServices.getResources();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
ReleaseId releaseId = kieServices.newReleaseId("org", "test",
id + ".0");
Resource resource = kieResources.newByteArrayResource(rule.getBytes());
kieFileSystem.write("src/main/resources/rule.drl", resource);
kieFileSystem.writePomXML(getPom(releaseId));
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem).buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("Build Errors:\n" + releaseId);
}
return kieServices.newKieContainer(releaseId);
}
String returns1 = "import java.util.List;\n" +
"\n" +
"rule \"rule1\"\n" +
"\tdialect \"mvel\"\n" +
"\twhen\n" +
"\t\tres : List( )\n" +
"\tthen\n" +
" res.add(\"1\");\n" +
"end";
String returns2 = "import java.util.List;\n" +
"\n" +
"rule \"rule1\"\n" +
"\tdialect \"mvel\"\n" +
"\twhen\n" +
"\t\tres : List( )\n" +
"\tthen\n" +
" res.add(\"1\");\n" +
" res.add(\"2\");\n" +
"end";
@Test
public void test() throws Exception {
CompletableFuture<?> f1 = CompletableFuture.runAsync(() -> {
for (int i = 0; i < 100; i++) {
List<String> res1 = new ArrayList<>();
createContainer(returns1,
1).newStatelessKieSession().execute(Arrays.asList(res1));
assertEquals(1, res1.size());
}
});
CompletableFuture<?> f2 = CompletableFuture.runAsync(() -> {
for (int i = 0; i < 100; i++) {
List<String> res2 = new ArrayList<>();
createContainer(returns2,
2).newStatelessKieSession().execute(Arrays.asList(res2));
assertEquals(2, res2.size());
}
});
f1.get();
f2.get();
}
private String getPom( ReleaseId releaseId ) {
return
"<?xml version=\"1.0\"
encoding=\"UTF-8\"?>\n" +
"<project
xmlns=\"http://maven.apache.org/POM/4.0.0\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
"
xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd\">\n" +
" <modelVersion>4.0.0</modelVersion>\n" +
"\n" +
" <groupId>" + releaseId.getGroupId() +
"</groupId>\n" +
" <artifactId>" + releaseId.getArtifactId() +
"</artifactId>\n" +
" <version>" + releaseId.getVersion() +
"</version>\n" +
"</project>\n";
}
}
{code}
concurrency issue when having multiple kie containers
-----------------------------------------------------
Key: DROOLS-1197
URL:
https://issues.jboss.org/browse/DROOLS-1197
Project: Drools
Issue Type: Bug
Components: core engine
Affects Versions: 6.4.0.Final
Reporter: Viacheslav Krot
Assignee: Mario Fusco
It seems there is some bug related to concurrency when creating multiple kie containers
in different threads.
Here is a test, that runs two threads, each has a loop creating a new kie container and
running rule with stateless session. I expect this usecase to work, but it fails
eventually - at some point in time kie container has loaded rules other than expected.
Is the test wrong or is there is a bug?
{{noformat}}
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.io.KieResources;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
public class ConcurrencyTest {
KieContainer createContainer(String rule) {
KieServices kieServices = KieServices.Factory.get();
KieResources kieResources = kieServices.getResources();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
Resource resource = kieResources.newByteArrayResource(rule.getBytes());
kieFileSystem.write("src/main/resources/rule.drl", resource);
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem).buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("Build Errors:\n" +
kb.getResults().toString());
}
return kieServices.newKieContainer(kb.getKieModule().getReleaseId());
}
String returns1 = "import java.util.List;\n" +
"\n" +
"rule \"rule1\"\n" +
"\tdialect \"mvel\"\n" +
"\twhen\n" +
"\t\tres : List( )\n" +
"\tthen\n" +
" res.add(\"1\");\n" +
"end";
String returns2 = "import java.util.List;\n" +
"\n" +
"rule \"rule1\"\n" +
"\tdialect \"mvel\"\n" +
"\twhen\n" +
"\t\tres : List( )\n" +
"\tthen\n" +
" res.add(\"1\");\n" +
" res.add(\"2\");\n" +
"end";
@Test
public void test() throws Exception {
CompletableFuture<?> f1 = CompletableFuture.runAsync(() -> {
for (int i = 0; i < 100; i++) {
List<String> res1 = new ArrayList<>();
createContainer(returns1).newStatelessKieSession().execute(Arrays.asList(res1));
assertThat(res1, hasSize(1));
}
});
CompletableFuture<?> f2 = CompletableFuture.runAsync(() -> {
for (int i = 0; i < 100; i++) {
List<String> res2 = new ArrayList<>();
createContainer(returns2).newStatelessKieSession().execute(Arrays.asList(res2));
assertThat(res2, hasSize(2));
}
});
f1.get();
f2.get();
}
}
{{noformat}}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)