CacheControl / CacheControl/json-rules-engine

Rule chaining not working with Promise.all

Aberta
#303 1 comentário 0 reações 0 responsáveis Ver no GitHub
Linguagem predominante
JavaScript
Estrelas
3.1k
Forks
507
Métricas de merge de PRs
Nenhum PR com merge em 30d

Descrição

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
```

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Direção de pesquisa

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.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
javascript
Domínio
backend
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
35/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.