I am simply testing some scripts for “fluttering contacts”
(want to set an item_delayed OPEN/CLOSE when a door/window stays at his state for a given time)
Its a very simple script to test.
The loop should simulate a multiple trigger of my rule.
I wanted to use “retrigger” but found out that the “context” will not be overwritten during retriggering. Now I decided to set the cancel manually in front of every timer.
But that is only the backround leading to this error in the headline.
I simple want to know if “production-Code” will have the same/similar problem, when I open/close many doors (I use a generic variant to write one rule and trigger it with all my doors)
I think this is fixed in 4.3 or this is simply a use case that is not supported.
The tl;dr is no JS rule can have more than one thread running at the same time. Because of that sleep (i.e. wait for) your rule is still running when it’s time to run the Timer. Because only one thread can run at a time when the Timer tries to run it gets the multi-threaded exception.
In 4.3 I think this use case is fixed with a lock so your timers will wait until the rule exits before running. But that’s not desirable in this code use case either because that means all your timers will wait for ten seconds and then run immediately.
To get the behavior you want with these blocks, replace the “1” block with i * 2 which will schedule the timer at the desired time but not keep this script running and preventing the timer from running when scheduled.
You mean
after << 1 >> seconds do with private timer “timer” with context << i >>
after << i*2 >> seconds do with private timer “timer” with context << i >>
Because you are scheduling timers to be two seconds from each other. Rather than waiting around two seconds between creating these timers, just schedule them to run two seconds apart in the first place. Then your rule can exit and the timer can get access to the thread and run as expected.
If you use a sleep in the rule that keeps the rule running at the same time a timer needs to run, at best your timer is going to wait until the rule exits to run which is not going to be the time you want it to run and at worst you will get this multi-threaded exception. In either case it’s not going to work how you want it to.
As a rule of thumb, don’t mix timers and sleeps. It’s best to avoid sleeps in the first place,