I have two rules. The first one should call the second one.
The implemented lock doesn’t touch the state of the trigger in the second rule.
Sometimes i see the correct behaviour in the log, but often i don’t
see both state variable (25 / 50)
How can i manage this?
import java.util.concurrent.locks.ReentrantLock
val ReentrantLock rollergroup_lock = new ReentrantLock()
rule "TEST"
when
Item testschalter changed
then
logInfo("test.rules"," TEST ***")
sendCommand(testwert,25)
sendCommand(testwert,50)
logInfo("test.rules"," TEST END ***")
end
rule "TEST1"
when
Item testwert changed
then
rollergroup_lock.lock()
var int wert = ( testwert.state as DecimalType ).intValue
logInfo("test1.rules",name + " TEST1 START: " + wert)
Thread::sleep(5000)
logInfo("test1.rules",name + " TEST1 END (" + wert + ")")
rollergroup_lock.unlock()
end
it’s just an example !
in real i have a rule which handles all items in a group and is triggered from another rule.
in my test i want to see something like:
TEST TEST ***
TEST TEST END ***
TEST1 TEST1 START: 25
TEST1 TEST1 END (25)
TEST1 TEST1 START: 50
TEST1 TEST1 END (50)
but often i see:
TEST TEST ***
TEST TEST END ***
TEST1 TEST1 START: 50
TEST1 TEST1 END (50)
TEST1 TEST1 START: 50
TEST1 TEST1 END (50)
This is because by the time the second rule has triggered and you retrieve the value in an integer (Which by the way you don’t need to do), the second command in the first rule has already executed and the item has updated to 50
it’s a race condition: when i put another sleep between the 2 sendcommand (500ms) it seem to work.
is there a way to explicitly wait for the end of execution of the second rule?
I think it is really important to understand the purpose here. Because as I read the code the lock doesn’t make any difference in the example, leaving it out you should produce the same behaviour, or even closer to the intended one, since the assignment of “wert” happens somewhat earlier.
without the lock the result isn’t sequential - it’s nested like this:
TEST TEST ***
TEST1 TEST1 START: 25
TEST TEST END ***
TEST1 TEST1 START: 50
TEST1 TEST1 END (25)
TEST1 END (50)
You want to run only one instance of the rule at any given time. Additional triggers should be queued. That is achieved with the lock. But it is not really your problem.
Which seems to be:
Whatever item has triggered the rule should be evaluated with the value it had at the time when the rule was triggered, even if updated in the meantime.
You may try to put the assignment before the lock, but this looks to me like a real-time computing requirement. That is hard to achieve with a system not specifically designed for rtc.
As I understand there might still be trap waiting: No more than 5 rules can run at any given time, and having a number of triggered rules sitting there waiting for the lock to become available might hit that limit. See also the “Why have my rules stopped running” link above.