jruizgit / rules

Durable Rules Engine
MIT License
1.14k stars 209 forks source link

durable_rules_engine.error: Could not create ruleset, error code: 113 #361

Open temmanuel-L opened 3 years ago

temmanuel-L commented 3 years ago

@jruizgit Hi, I've got a ruleset creation problem. The purpose of the ruleset is to organize several signal to formalize an event, thus the property of each signal should satisfy the rule. Also, there should be a time window to restrict time duration between the signals which fit property requirement. The ruleset is organized in JSON. I've tried on some simple rules, which can be loaded by "get_host().set_rulesets()" and participate into the process of identify events. It looks like something below.

  "nari_test7": {
    "r_0": {
      "all": [
        {
          "No1": {
            "$and": [
              {
                "status": "201"
              },
              {
                "$or": [
                  {
                    "$gte": {
                      "time": {
                        "$sub": {
                          "$l": {
                            "No2": "time"
                          },
                          "$r": 20
                        }
                      }
                    }
                  },
                  {
                    "$lte": {
                      "time": {
                        "$add": {
                          "$l": {
                            "No2": "time"
                          },
                          "$r": 20
                        }
                      }
                    }
                  }
                ]
              }
            ]
          }
        },
        {
          "No2": {
            "$and": [
              {
                "norm_bay": "low capacity"
              },
              {
                "norm_equip": "breaker location"
              },
              {
                "status": "1"
              }
            ]
          }
        }
      ],
      "pri": 1,
      "run": "func_r_0"
    }
  }
}

You can see that there are only two signals in the events, the intention of time restrictions of the two signals is not time-sequential, meaning either one could be identified as the first part of the event. and the formation above is OK for the solution. However, when it's about dozens of signals as well as untime-sequential, the writing will be quite overstaffed, for each signal should be compared with the others to measure time duration. When I load these rulesets, the engine shows errors below:

"durable_rules_engine.error: Could not create ruleset, error code: 113"

I check the source code and found the error code referring to "ERR_EXPRESSION_LIMIT_EXCEEDED"(rules.h), which are predefined as 32 in rete.h file. But these source code can only be viewed in your GIT project, I don't know how to adjust the number in the program to fit my needs. Really appreciate for some suggestions

jruizgit commented 3 years ago

Hi, thanks for posting the question. The engine limits the size of expressions to 32 terms (term1 AND term2 AND term3...). Unfortunately the limit is not configurable. The limit is intended for improved memory usage and performance. How complex can your expressions be? What would you set this limit to?

temmanuel-L commented 3 years ago

If there are 10 signals in the events, besides matching each signal's attribute, which needs 10 'AND' terms to do that(each signal has several attributes to match), time limits should also be tied to the rule. If these 10 signals are bounded in a 20 seconds time window, and the event allows any signal in any position, meaning these signal are unordered. To accomplish that, I used the format mentioned above to compare each combination of a two-signal pair's timestamp, since the combination number is 45, so another 45 'or' terms should be added to the rule. one such term looks like below:

      "$or": [
                  {
                    "$gte": {
                      "time": {
                        "$sub": {
                          "$l": {
                            "No2": "time"
                          },
                          "$r": 20
                        }
                      }
                    }
                  },
                  {
                    "$lte": {
                      "time": {
                        "$add": {
                          "$l": {
                            "No2": "time"
                          },
                          "$r": 20
                        }
                      }
                    }
                  }
                ]

Therefore, 55 terms are needed for this situation. Actually, sometimes, the signal number might reach to utmost 30, which leads to 465 terms. I believe tweaking the limit to 512 would be sufficient. The question is how to adjust this parameter? For it's already integrated into the extention of the lib.