[jboss-jira] [JBoss JIRA] (DROOLS-1197) concurrency issue when having multiple kie containers

Mario Fusco (JIRA) issues at jboss.org
Fri Jun 3 12:52:00 EDT 2016


     [ https://issues.jboss.org/browse/DROOLS-1197?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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)


More information about the jboss-jira mailing list