Using cache.shared
in JavaScript rules can lead to unexpected java.lang.IllegalStateException: Multi threaded access requested by thread
#4413
Labels
bug
An unexpected problem or unintended behavior of the Core
Expected Behavior
The
cache.shared
object is documented as allowing any script to access it and "share" information. The documentation comes with an example forcache.private
that we can adjust to usecache.shared
:We would expect the above code to work when used by two rules; every time either of the rules fires, the code is executed, the counter increased and the old value logged.
Current Behavior
cache.shared
allows sharing JavaScript objects between two rules. JavaScript code for two different rules will get executed in two different threads. The JavaScript engine used by OpenHAB is not designed to be run in multiple threads simultaneously. The Java code is aware of this and will throw ajava.lang.IllegalStateException
exception when two threads attempt to access the same JavaScript object. The message associate with this exception is:This exception unexpectedly stop the execution of the rule using
cache.shared
and breaks its functionality.Possible Solution
cache.shared
to share information between multiple rules. Obviously, limiting the amount of sharing seriously reduces the usefulness ofcache.shared
, so this is more of a stop-gap than a solution IMHO.Steps to Reproduce (for Bugs)
This issue quite easy to reproduce If we create two JavaScript rules that accesses a shared object over a prolonged period and execute them at nearly the same time. In this set-up, the JavaScript code is almost guaranteed to simultaneously attempt to access the object, which triggers the exception. Here's a step by step guide to do this:
Test1
andTest2
Test1
that fires every second (cron:* * * * * ? *
)Test2
does not need a trigger: you will run it manually later.Test1
andTest2
to execute the same JavaScript code (found below).Test1
(the cron rule)Test2
Here is the code used in both rules:
Here is an example log output showing the exception after starting the first rule and manually running the second:
The exception can happen in either
Test1
orTest2
depending on timing.Context
I am creating a queue for audio files to be played. The queue is stored in an
Array
incache.shared
. Any rule can useArray.push()
to add a file to the queue. A dedicated rule uses a timer to repeatedly check if it is time to play the next file and usesArray.shift()
to get the next file from the queue and send it to the player. This system breaks when two rules try to add or remove files to/from the queue at the same time. These exceptions make the system unreliable.Your Environment
The text was updated successfully, but these errors were encountered: