CacheControl / CacheControl/json-rules-engine

Rule chaining not working with Promise.all

未關閉
#303 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
主要語言
JavaScript
星號
3.1k
分支
507
PR 合併指標
30 天內沒有已合併 PR

描述

If I run the engine sequentially, I am getting the desired result. If I run it in parallel, I am getting results only for the first run.

**student-fav-subject.js**

```
const { Engine } = require("json-rules-engine");

const apiClient = require("./student-api-client");

let engine = new Engine();

async function start() {
let mathematicsSubjectRule = {
conditions: {
all: [
{
fact: "student-information",
operator: "contains",
value: "Mathematics",
path: "$.subjects",
},
],
},
event: { type: "studies-mathematics" },
priority: 10,
onSuccess: async function (event, almanac) {
almanac.addRuntimeFact("studiesMathematics", true);
},
onFailure: function (event, almanac) {
almanac.addRuntimeFact("studiesMathematics", false);
},
};
engine.addRule(mathematicsSubjectRule);

let physicsFavoriteRule = {
conditions: {
all: [
{
fact: "studiesMathematics",
operator: "equal",
value: true,
},
{
fact: "student-information",
operator: "equal",
value: "Physics",
path: "$.favoriteSubject",
},
],
},
event: {
type: "physics-favorite-subject",
params: {
message: " has Physics as their favorite subject",
},
},
};

engine.addRule(physicsFavoriteRule);

engine.addFact("student-information", function (params, almanac) {
console.log("loading student information...");
return almanac.factValue("studentName").then((studentName) => {
return apiClient.getStudentInformation(studentName);
});
});

engine.on("success", (event, almanac, ruleResult) => {
almanac.factValue("studentName").then((studentName) => {
switch (event.type) {
case "physics-favorite-subject":
console.log(
studentName,
"HAS".green,
"Physics as their favorite subject"
);
}
});
});

engine.on("failure", (event, almanac, ruleResult) => {
almanac.factValue("studentName").then((studentName) => {
switch (event.type) {
case "physics-favorite-subject":
const studiesMathResult = ruleResult.conditions.all.find(
(condition) => condition.fact === "studiesMathematics"
);
if (studiesMathResult) {
if (studiesMathResult.result) {
console.log(
studentName,
"DOES NOT".red,
"have Physics as favorite subject"
);
} else {
console.log(
studentName,
"CANNOT NOT".red,
"have Physics as favorite subject as they do not study Mathematics"
);
}
}
}
});
});

Promise.all([
engine.run({ studentName: "samuel" }),
engine.run({ studentName: "joseph" }),
engine.run({ studentName: "anthony" }),
]);

// await engine.run({ studentName: "samuel" });
// await engine.run({ studentName: "joseph" });
// await engine.run({ studentName: "anthony" });
}

start();

```

**student-api-client.js**

```
"use strict";

require("colors");
const fs = require("fs");

let studentData = require("./student-data.json");

/**
* mock api client for retrieving student information
*/
module.exports = {
getStudentInformation: (studentName) => {
const message = 'loading student information for "' + studentName + '"';
console.log(message.dim);
return new Promise((resolve, reject) => {
setImmediate(() => {
resolve(studentData[studentName]);
});
});
},
};

```

**student-data.json**

```
{
"john": {
"favoriteSubject": "Mathematics",
"subjects": ["Physics", "Mathematics"]
},
"anthony": {
"favoriteSubject": "Physics",
"subjects": ["Physics", "Mathematics"]
},
"george": {
"favoriteSubject": "History",
"subjects": ["History", "Mathematics"]
},
"samuel": {
"favoriteSubject": "Physics",
"subjects": ["Physics", "History", "Geography", "Chemistry"]
},
"joseph": {
"favoriteSubject": "Economics",
"subjects": ["Economics", "Mathematics", "History"]
}
}
```

## Output

### Running sequentially

```
loading student information...
loading student information for "samuel"
samuel CANNOT NOT have Physics as favorite subject as they do not study Mathematics
loading student information...
loading student information for "joseph"
joseph DOES NOT have Physics as favorite subject
loading student information...
loading student information for "anthony"
anthony HAS Physics as their favorite subject
```

### Running parallelly (Promise.all)

```
loading student information...
loading student information...
loading student information...
loading student information for "samuel"
loading student information for "joseph"
loading student information for "anthony"
samuel CANNOT NOT have Physics as favorite subject as they do not study Mathematics
```

貢獻指南

這個儲存庫沒有索引到貢獻指南

研究方向

Start by reproducing the Promise.all example in the issue, then inspect Engine.run and the runtime-fact handling used by almanac.addRuntimeFact. Done means the parallel runs produce the corresponding results and events for samuel, joseph, and anthony, matching the sequential behavior.

由索引模型根據 Issue 內容生成。

評估

技術堆疊
javascript
領域
backend
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。