Problem with rule locking per ReentrantLock

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

What are you trying to achieve?
In your second rule, you lock the thread and then do a logInfo, sleep for 5 seconds and do another logInfo

Why are you locking the rule?
Use a timer instead of the 5 seconds sleep.

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

That looks like a race condition: The second sendCommand is executed before the first rule trigger can acquire the lock.

Looking at the timestamps in the event.log might be illuminating.

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)

Maybe this two threads give you a inspiration why sleep is not preferable and how to solve it with timers.

That’s bring us back to, what are you trying to achieve. What is the end result you want?

Ok, let me try formulate your goal:

  • 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.

you’re right.
when the assignment is before the lock the result is ok…

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.