setTimeout throws 'Multi Threaded Access Requested' exception

  • Platform information:
    • Hardware: Intel x86-x64
    • OS: Windows 10 x64 Pro
    • Java Runtime Environment: Zulu JDK 11.54.23
    • openHAB version: openHAB 3.3.0.M1

Hi,

I have the following script:

test("1");
test("2");
test("3");

function test2(id) {
  console.info(id);
}

function test(id) {
  console.info(id);
  setTimeout(test2, 5.0*1000, id);
}

Log output is:

2022-03-01 15:41:08.280 [INFO ] [n.script.ui.SkriptRollladensteuerung] - 1
2022-03-01 15:41:08.343 [INFO ] [n.script.ui.SkriptRollladensteuerung] - 2
2022-03-01 15:41:08.343 [INFO ] [n.script.ui.SkriptRollladensteuerung] - 3
2022-03-01 15:41:13.328 [INFO ] [n.script.ui.SkriptRollladensteuerung] - 1
2022-03-01 15:41:13.359 [INFO ] [n.script.ui.SkriptRollladensteuerung] - 3
2022-03-01 15:41:13.359 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job failed and stopped
java.lang.IllegalStateException: Multi threaded access requested by thread Thread[OH-scheduler-213,5,main] but is not allowed for language(s) js.
	at com.oracle.truffle.polyglot.PolyglotEngineException.illegalState(PolyglotEngineException.java:129) ~[bundleFile:?]
	at com.oracle.truffle.polyglot.PolyglotContextImpl.throwDeniedThreadAccess(PolyglotContextImpl.java:940) ~[bundleFile:?]
	at com.oracle.truffle.polyglot.PolyglotContextImpl.checkAllThreadAccesses(PolyglotContextImpl.java:799) ~[bundleFile:?]
	at com.oracle.truffle.polyglot.PolyglotContextImpl.enterThreadChanged(PolyglotContextImpl.java:629) ~[bundleFile:?]
	at com.oracle.truffle.polyglot.PolyglotEngineImpl.enterCached(PolyglotEngineImpl.java:1885) ~[bundleFile:?]
	at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:112) ~[bundleFile:?]
	at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:85) ~[bundleFile:?]
	at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:102) ~[bundleFile:?]
	at com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invoke(PolyglotFunctionProxyHandler.java:154) ~[bundleFile:?]
	at com.sun.proxy.$Proxy228.apply(Unknown Source) ~[?:?]
	at org.openhab.core.model.script.actions.ScriptExecution.lambda$1(ScriptExecution.java:100) ~[bundleFile:?]
	at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$12(SchedulerImpl.java:184) ~[?:?]
	at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$1(SchedulerImpl.java:87) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
	at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: com.oracle.truffle.api.TruffleStackTrace$LazyStackTrace

Why is this happening?

How can I create multiple timers in one script instead?

See

Of course I already read that thread, but it doesn’t contain a solution and it seems they are talking about calling a script (with included timer) multiple times. My script runs only 1x at the same time, but should be able to create multiple timers. So I don’t understand why those timer callbacks are not running synchronously each one after another.

So I only allowed to use one timer per script?

Background:

Depending on the time and a lot of other states I want to control up to 8 (and in the future even more) roller shutters. Sometimes it happens, that one of those roller shutters not getting the signal to go up/down, so that I have to resend the signal.

My idea was to get the current roller shutter level, send the new value and after e.g. 5s I want to check if the new current value is different than the old current value, if not I resend the new value, otherwise everything is OK.

So if there is no solution to create multiple timers for each roller shutter, I have to create only one, and have to store all current values in a list and compare them with the new current values to determine which roller shutters needs to get the new value again.

Well, of course.

No, it doesn’t.

That is the current situation, yes.
To overcome the limitation, use another rule scripting language temporarily.