建立Kie会话线程安全吗?

时间:2019-04-10 11:04:34

标签: java drools

我们有一些代码可以并行创建大约1500个Kie会话,我的印象是它不是线程安全的。我检查了所有无状态的代码,难题中最后缺少的部分是以下代码:

public KieSession buildSession(Config configuration) throws InvalidConfigurationException {
    KieFileSystem kfs = this.kieServices.newKieFileSystem();

    addRules(config, kfs); // Stateless

    this.kieServices.newKieBuilder(kfs).buildAll();

    KieBaseConfiguration kieBaseConfiguration = KieServices.Factory.get().newKieBaseConfiguration();
    kieBaseConfiguration.setOption(EventProcessingOption.STREAM);

    KieContainer kieContainer = this.kieServices.newKieContainer(this.kieServices.getRepository().getDefaultReleaseId());
    KieBase kieBase = kieContainer.newKieBase(kieBaseConfiguration);

    return buildSession(configuration.getHouseholdId(), kieBase);
}

public KieSession buildSession(KieBase kieBase) {
    KieSessionConfiguration kieSessionConfiguration = KieServices.Factory.get().newKieSessionConfiguration();
    kieSessionConfiguration.setOption(ClockTypeOption.get("pseudo"));

    KieSession kieSession = kieBase.newKieSession(kieSessionConfiguration, null);

    return kieSession;
}

我们将规则作为字符串添加到文件系统中。该文档说:

However, since in this case the KieFileSystem doesn’t contain any pom.xml file (it is possible to add one using the KieFileSystem.writePomXML method though), Kie cannot determine the `ReleaseId` of the KieModule and assign to it a default one.
This default `ReleaseId` can be obtained from the KieRepository and used to identify the KieModule inside the KieRepository itself.

所以我的猜测是,在这种情况下,因为我们在文件系统中没有pom文件,所以我们将始终使用默认的ReleaseId并具有用于存储Kie模块的临时变量的等效项。然后两个线程可以覆盖此变量,这意味着在某些情况下该方法将为配置返回错误的kie会话。

这是正确的吗?如果没有,我该如何解决?

1 个答案:

答案 0 :(得分:0)

对不起,我迟到了。

我的假设实际上是正确的,当您创建一个新的KieFileSystem时,它会在存储库中使用发行版ID注册。如果不指定发行版ID,则使用默认的发行版ID,您可以覆盖另一个线程的文件系统。看起来是一个哈希图,其中所有线程都使用相同的密钥。

所以我们创建自己的发行ID的操作和最终代码如下

ReleaseId releaseId = new HouseholdReleaseId(configuration.getHouseholdId()...);

KieFileSystem kfs =
   this.kieServices.newKieFileSystem()
      .generateAndWritePomXML(releaseId); // Set the release id here.

// Do all the stuff with the file system.

KieContainer kieContainer = this.kieServices.newKieContainer(releaseId); // Same release id.
KieBase kieBase = kieContainer.newKieBase(...);