Skip to content
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

[jsscripting] Fix multi-threading issues in UI-based scripts #17510

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

florian-h05
Copy link
Contributor

@florian-h05 florian-h05 commented Oct 5, 2024

This fixes illegal multi-thread access requests to the GraalJS context for UI-based rules.

Those have two causes:

  1. The execution of pre-compiled scripts (refs [rules] Add support for pre-compilation of conditions and actions openhab-core#4289) is not synchronized for JS Scripting.
  2. If the script is currently executed and a timer is already waiting to acquire the lock, illegal multi-thread access is requested even though the locking mechanism is in place. I cannot really explain that behaviour, but it seems to be a timing issue in the milliseconds range ... When adding logging, the logger tells me that the timer acquires the lock before its released by the script execution. And when attaching a debugger to verify the correct functionality of the locking mechanism, the issue is gone, which IMO again speaks for a timing issue ...

This is fixed through the following:

  1. Add support for synchronized execution of pre-compiled scripts in [automation] Add support for synchronized execution of compiled scripts openhab-core#4402 and implement the Lock interface in the ScriptEngine that gets passed to openHAB Core.
  2. Add a Thread.sleep of 1/100 second to the Lock unlocking logic inside the add-on.

The issue can be reproduced by pasting the following script into a script inside the UI and running it:

console.log('Sleeping...')
setTimeout(() => {
  console.log('Timer ran.')
}, 1000)
setTimeout(() => {
  console.log('Timer ran.')
}, 2000)
setTimeout(() => {
  console.log('Timer ran.')
}, 3000)
java.lang.Thread.sleep(10000)

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
… Core can lock and unlock when executing the pre-compiled script

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
…-threading issues with UI-based scripts

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
@florian-h05 florian-h05 added bug An unexpected problem or unintended behavior of an add-on awaiting other PR Depends on another PR labels Oct 5, 2024
@J-N-K J-N-K removed the awaiting other PR Depends on another PR label Oct 6, 2024
@@ -230,7 +229,10 @@ public Path toRealPath(Path path, LinkOption... linkOptions) throws IOException
protected void beforeInvocation() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is this method called (when executing a script)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is called everytime before the engine executes code, there is only one exception: When a compiled script is executed, this won't be called (it has been called when the script was compiled, so the setup already happened).

See https://github.com/openhab/openhab-addons/blob/main/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/scriptengine/InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable.java, there is beforeInvocation called.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An unexpected problem or unintended behavior of an add-on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants