ReentrantLock: avoid concurrency with timer

Hi all, also if i used openhab for more than 2 years sometimes i feel like i’m lost in a glass of water :slight_smile:
I would like to avoid multiple instances of a rule running togheter: the docs suggest to use the ReentrantLock function. So i wrote this rule:

import java.util.concurrent.locks.ReentrantLock
val ReentrantLock Fin401  = new ReentrantLock()
 
rule "Apertura chiusura finestre"
when
         Item FinCamera401_Status changed
then
         Fin401.lock()
     try {
         createTimer(now.plusSeconds(15), [ |
           // do some stuff here
         ])
     } finally {
         Fin401.unlock()
     }
end

Basically i would like that any new status of FinCamera401_Status (it may change many times in few seconds) can fire the rule again only after everything inside the try block have been executed.
How can i achieve this?
The above rule doesn’t work as the try and the finally blocks seems to run in parallel, while i would like that Fin401.unlock() release the lock only after all the logics inside the try block have been executed (there is a timer, so at least it should retain the rule for 15 seconds).
Thanks for any help and sorry for my elementary english :slight_smile:

Nope. It’s that you have misunderstood how createTimer() works. It does what the name suggests - it creates an independent Timer for future execution, that’s all. Then the rule carries on. The rule never waits, the Timer itself is a free agent. The rule completes and exits long before the Timer code runs.

Here’s a way not to do X until a timer has completed. It’s a very common way to use Timers seen in most examples.

var Timer myTimer = null

rule "testing"
when
    Item someItem changed
then
    if (myTimer === null) {
           // no timer exists yet
        myTimer = createTimer(now.plusSeconds(15), [ |
            // do stuff
            myTimer = null // tell the world we are finished
        ])
    } else {
        // timer already running
        // do other stuff, like reschedule the timer if you want
    }
end

This basic approach is suitable for e.g. lighting triggered by motion. But it will not queue up trigger events to all do the same thing in due course - that is much more complex.

Thanks @rossko57 for helping me pointing out how timers works :slight_smile:
Now everything works as expected. Now i will lurk a bit into the forum how can i queue commands to the same item, avoiding concurrency of commands.
Thanks again!

Note that if you continue to queue new commands faster than you process them, you will eventually run out of memory.

Don’t trust try, catch, finally I rules dsl, esp.if you are using lambdas.
Doing more advanced stuff I recommend looking at jython, habapp or any of the oh3 supported languages.
I’m rewriting all my rules in pure java now where I can use completable futures, synchronized proper try catch and other tools.

@Seaside
Honestly i’m just a iot enthusiast, not a programmer. Now i feel comfortable with DSL rules. Also if my code surely isn’t the best in town i could realize pretty complex rules and scenarios.
The learning curve was pretty high in my case, and now i’m a little bit confused about oh3. Especially if i had to start again with new languages. So for the moment i think i will stay on OH2

1 Like

If you are comfortable with DSL, use it. You don’t have to ride anyone else’s hobbyhorse.
DSL remains fully supported in OH3 and you can carry your OH2 rule set forward.
(There are one-time changes in date-time handlng due to the underlying Java update.)

1 Like

I agree, but it’s still good to know the limitations of rules dsl.

/S

1 Like