我们有一些代码可以并行创建大约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会话。
这是正确的吗?如果没有,我该如何解决?
答案 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(...);