-
-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate Blockly to JS Scripting (GraalJS) #1597
Comments
I'm under the same assumption.
In openhab/openhab-core#2433 (comment) I argued that once GraalJS becomes the default JS engine, maybe by the time OH4 is released it should "own" the generic The jury's out on whether it's a good idea, but in theory it could go smoother than we would normally expect, without much needing to alter scripts (Blockly or not) if the "global"/scope variables like That way the Blockly script actions would keep the |
When using openhab-js to get the Item, the
A lot of that has been worked out I believe. Thread.sleep is supported without throwing an error now, IIRC, and @florian-h05 did a lot of work to add locks around Timers so they cannot run at the same time and generate that multithreaded exception any more. You can still run into that exception if two rules try to call the same other rule at the same time, but within a given rule it's no longer a problem.
I tried out OH 4 snapshot today and ran into this. We definitely need to be able to edit that. In fact, it'd be nice to edit other stuff about a Script too like tags, name, and description. But that's a discussion for another issue. ;-) Maybe adding a "Code" tab to see the YAML even for Scripts would be sufficient?
let/const are still a problem in UI rules. The context gets reused so the second time the rule runs it'll complain that you can't redeclare a const or let. So this is a good thing. |
If you want everything that was available in Nashorn in the global scope of GraalJS, it should be enough to add the following: Object.assing(this, require('@runtime');
(Referencing my first answer …) But I am concerned that user written scripts run into muti-threading problems when they create timers from the not threadsafe APIs (ScriptExecution from core). So for user written scripts, the MIME type should be swapped to use Nashorn. We therefore need to allow the user to easily change the type of scripts in the UI (no YAML, no REST API calls).
That‘s because Graal behaves much more like Node than Nashorn does. As Rich already pointed out, openhab-js returns the state as string so concatenating Item state and string works fine. FYI: openhab-js tries to avoid to return any raw Java objects, instead e.g. for Item state and Thing status we use string. So that concern is solved.
Yes, Nashorn allows multi-thread access to the script context, Graal doesn‘t. Graal is this way to emulate the single-threaded concept of Node, but Graal is missing the event loop. Thanks to the multi-thread access synchronization, it is also possible to use Please note that when you cancel a timer that is currently executing, you‘ll get a WARNING that says something like Thread interrupted, or if you cancel a executing
I wan‘t aware of this, this needs a change in core but it shouldn‘t be too complicated. I‘ll talk about this with the core maintainers. @ghys @rkoshak |
Thanks for the detailed & interesting explanations. So either we choose to keep the media/MIME types as they are now, or proceed with the above at the risk of potentially breaking existing scripts, which could be mitigated by:
|
I totally agree. @rkoshak seems to also agree here, see openhab/openhab-addons#14005 (comment).
I agree here as well as on your options described after. I'm not sure how 2 is meant, but IMO we shouldn't append code to Nashorn user scripts to make them work with Graal, but instead recommend to use Nashorn for them. |
Sorry that was unclear indeed. I was thinking about in-place migration techniques from Nashorn to Graal for user scripts (as Blockly would be handled by a save). One of these could perhaps be to start adding |
Or as part of the upgrade perhaps?
At least in the case of a cancelled timer, which is a normal thing to do, it should be INFO, not WARN level I would think. Maybe we don't have control over that? It's not unusual to have lots of Timers whose only purpose for existing is to be canceled. Put another way, the fact that it's cancelled is the "good" path and only if the Timer runs has something gone off. Getting a WARN level log on the good path is jarring and I know the first thing we'll see is "how do I fix this warning in my logs?" from users.
👍 I haven't brought it up myself because I haven't yet decided if this is an antipattern or not. But it should probably be consistent and if we can fix this, we probably should.
That seems reasonable to me. From the end user's perspective the blocks are the code. So we might need to hold their hand a little bit but it's reasonably to expect to need to do some manual steps to go between major release versions. |
I am not sure how much "automatic" stuff we want and how complicated it is to automate such things. Before we implement that, we should implement the "manual" ways.
I've just checked what GraalJS does when you cancel the timer from it's own callback function, I haven't got a warning :-) var timer = actions.ScriptExecution.createTimer('timer1', time.toZDT().plusSeconds(10), () => {
console.log('Timer is now running, attempting to cancel it...')
timer.cancel()
console.log('Timer has been cancelled.')
}) For the case that a timer is using So it seems like we don't have to expect any I've updated the issue description on top. |
With the |
If Blockly uses the |
I only bring that up because I think we will need to support |
Does it make sense then to mention it later in the docs that it is not recommended to cancel a timer in a shared cache? |
I still think it's OK to cancel it. Maybe just a warning that you'll see warnings in the logs but they are harmless. |
I am actually not - please see my comment on openhab/openhab-distro#1455. |
Since the PR has been merged, we should start solving the remaining issues:
|
With the Blockly implementation of timers, it is not possible to store a timer in the shared cache and therefore this issue can never occur. We don‘t need to add such a note to the docs. Is this limited to Blockly or in general? My concern with that is one of the biggest reasons to share variables between rules is explicitly to share Timers (e.g. one rule that checks for existence, one that creates, one that cancels. |
This is no general limitation, and it is possible to support this as well from Blockly. |
@rkoshak you challenged me ;-)
|
Awaiting #1601.
The current situation
In #1170, a first solution how to make the Blockly blocks compatible with JS Scripting (GraalJS) was proposed, however this solution has two problems:
To port Blockly to JS Scripting, we therefore came to the conclusion (also in #1170), that Blockly should use the integrated openhab-js library instead of the raw Java APIs.
Our approach/solution
Blockly maintainer @stefan-hoehn and I (openhab-js and JS Scripting addon maintainer) joined forces and decided on the following approach:
Concerns
string
.setTimeout
,setInterval
,createTimer
) create threadsafe timers andThread.sleep
also works.Thread.sleep
can to a thread/sleep interrupted warning: This is by design, but it will never occur with Blockly or generally from a single script (multi-thread synchronization makes it impossible to callcancel
on a currently executing timer). This can only happen when a currently executing timer created by script a is cancelled by script b (to make this possible, the timer must be shared across the scripts).sharedScript
. We should address the log issue.To Dos
With the openHAB 4 release on the horizon, which removes Nashorn from core but readds it to the addons, I propose to change/extend that approach a little bit (under the assumption that GraalJS is installed by default, Nashorn not):
Interesting links
/cc @stefan-hoehn @ghys @rkoshak
The text was updated successfully, but these errors were encountered: