[rules] JSRule: Add support for creating "standard" rules (not SimpleRule)#490
[rules] JSRule: Add support for creating "standard" rules (not SimpleRule)#490florian-h05 merged 7 commits intoopenhab:mainfrom
Conversation
…Rules) Signed-off-by: Florian Hotze <dev@florianhotze.com>
|
@Nadahar This enables JSRule to create "standard" openHAB rules in addition to its ability of creating SimpleRules. |
There was a problem hiding this comment.
Pull Request Overview
This PR enhances the JSRule functionality by adding support for creating "standard" rules (RuleImpl) in addition to the existing SimpleRule implementation. The key enhancement is introducing a dedicatedContext option that allows rules to run in isolated contexts, preventing interference between rule executions.
- Added support for creating standard rules with dedicated contexts via the
dedicatedContextconfiguration option - Refactored JSRule implementation to support both SimpleRule and standard Rule creation paths
- Updated variable naming and documentation for consistency and clarity
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Signed-off-by: Florian Hotze <dev@florianhotze.com>
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 1 out of 3 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Signed-off-by: Florian Hotze <dev@florianhotze.com>
Signed-off-by: Florian Hotze <dev@florianhotze.com>
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 1 out of 3 changed files in this pull request and generated 1 comment.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
FYI you may use this for testing: const { rules, triggers, utils } = require('openhab')
function myFunction() {
console.log('myFunction()')
}
rules.JSRule({
name: 'Shared Context Rule',
execute: (event) => {
myFunction()
utils.dumpObject(this)
}
})
rules.JSRule({
name: 'Dedicated Context Rule',
triggers: triggers.ItemCommandTrigger('test_switch'),
execute: (event) => {
myFunction() // expect this to fail
utils.dumpObject(this)
java.lang.Thread.sleep(5000)
},
dedicatedContext: true
}) |
Please give me some time to study it, I'm "slow" when it comes to these things 😉 |
|
I added a comment to one of the CoPilot comments that have been "resolved". I'm not sure if you'll see that or not, so this is a heads-up. |
|
I have to ask some really stupid questions here, but how do I proceed to use this version instead of the standard, so that I can test it? Can I just overwrite some file somewhere? |
|
That‘s actually no stupid question at all. You have three options:
Then, disable injection caching in the settings of the JS Scripting add-on. |
|
Just let me know once you are finished with testing. |
You don't have to wait on my testing for this, you probably know that it works. But, for me to evaluate it, I must test and try to understand what happens, and this is slow because I'm in so unfamiliar territory. But I can just as well do that after you merge it. |
|
About the naming, I think it looks good 👍 |
|
Did you ever find my comment about how to attach the source?
I always made to raise this anyway, so when I saw the code here, I might as well mention it now. It's very little change, basically, you move it to the Rule instead of the Action, and use the key ruleConfiguration.put('type', SCRIPT_TYPE);
ruleConfiguration.put('source', '// Code to run when the rule fires:\n// Note that Rule Builder is currently not supported!\n\n' + ruleConfig.execute.toString()); |
|
This is amazing 🥳 This opens up the possibility for JS rules that can run in parallel (if you don't need shared functions) and that can be duplicated in MainUI (if that has any value). But, you could also implement support for making rule templates from JS (if there is any point in doing that, of course) using this technique. The approach could also be used to enable scripted conditions, also for Edit: This means that I'm done "testing". All I really wanted to do was to inspect the rule object it produced, and it looks great 👍 |
|
If you want to take this "far out there", maybe you could find a way to define another "dedicated context" in the same file where shared functions could be defined. This "dedicated context" could then be "injected" into the other dedicated context, for example by registering it as a Just disregard if you're currently not looking for a challenge, this is just ideas that pop into my head of what might be possible to achieve 👼 |
| */ | ||
| function _createRule (ruleUID, ruleConfig) { | ||
| let script = ruleConfig.execute.toString(); | ||
| script = script.match(/(function)?[^{]+\{([\s\S]*)}$/); |
There was a problem hiding this comment.
So, this is where "the magic" happens? I don't quite get that you can extract the source code just by calling toString() on the function, but it's great that you can.
There was a problem hiding this comment.
You can call toString on any JS function and get its code, except it's a function provided by the runtime, then you'll only receive a string saying the function body is native code. All I have to do here is extract the body of the function.
Nadahar
left a comment
There was a problem hiding this comment.
To the extent that I understand what happens, this LGTM!
|
I will adjust the attachment of the source as you suggested and write docs before merging |
Signed-off-by: Florian Hotze <dev@florianhotze.com>
The thing is, JSRule has to support both SimpleRule and standard Rule, and: a. There is no SimpleConditionHandler
If you want to share across multiple contexts, you can create your own npm module. This would be the JS-way of sharing functions and classes. |
It should be possible to make a When I'm talking about Conditions, I'm not really thinking of the evaluations that you do when you decide how to execute the Action. I'm thinking of Conditions that prevents the Rule from running entirely (those that would essentially just return from the Action without doing anything) - basically what handles the nuance that the Trigger doesn't. Doing it this way may not be much more performant (except that as long as we're not dealing with a "SimpleCondition", it can run in parallel with other operations), but it would certainly make the log/events "more logical", so that a rule wasn't reported as "run" all the times when it isn't really, but just returns. However, when I think about it, a "SimpleCondition" might be a bad idea because of the locking, at least for JavaScript (and other engines that require an engine lock): As far as I can remember, the |
Signed-off-by: Florian Hotze <dev@florianhotze.com>
Signed-off-by: Florian Hotze <dev@florianhotze.com>
That's correct in case of events, I have never noticed a log about rule runs though.
And you also add the overhead (even if its little) of an additional engine ... |
No description provided.