(OH 1.x and OH 2.x Rules DSL only] Why have my Rules stopped running? Why Thread::sleep is a bad idea

That’s pretty cool - thanks for pointing me in the right direction! I don’t mean to hijack this thread/can ask my question(s) in the proper channels, but is there any way to set this terminal to connect to the machine housing my openHAB server? I use VSCode on both a Windows machine and the Linux machine where openHAB resides - it would be so great to be able to run Linux commands remotely! I’ve tried to figure out the “Exec” binding for like six months now and have more or less given up at this point :frowning:

Run ssh from that terminal to log into the remote machine. Search Google for how to set up ssh on a Windows machine.

1 Like

Do you run a desktop on the Linux system with VSCode or are you using the Remote-SSH extension? If not, I can recommend you to look it up. :grinning:

1 Like

Hi! Please help convert my rule right way using timers.
I need to flash by oled display On and OFF for 4 times:

		if (Alarm.state == ON) {
				(1..4).forEach[
					if (Alarm.state == ON){
						ESP_Lamp_Inverse.sendCommand(ON)
						Thread::sleep(500)
					} 	
					ESP_Lamp_Inverse.sendCommand(OFF)
					if (Alarm.state == ON){
						Thread::sleep(500)
					} 	
				]
			}

As your code is not complete, I can only guess, but maybe this is what you want:

// define global vars outside the rule on top of file
var Timer tOled = null
var int iOled = 0
...


// inside the rule
...
if(Alarm.state == ON) {
    tOled?.cancel                                          // cancel any existing timer
    iOled = 0                                              // initialize counter
    tOled = createTimer(now.plusMillis(10), [ |            // initialize timer
        iOled ++                                           // count up
        // odd -> ON, even -> OFF
        ESP_Lamp_Inverse.sendCommand(
            if(ESP_Lamp_Inverse.state != ON) ON else OFF)  // toggle light
        if(iOled < 8)                                      // 2 times 4 
            tOled.reschedule(now.plusMillis(500))          // next step
        else 
            ESP_Lamp_Inverse.sendCommand(OFF)              // ensure light is OFF
    ])
} else {
    tOled?.cancel
    ESP_Lamp_Inverse.sendCommand(OFF)
}

Thank you!

A little update on the “Aspirin Fix” for OH 2.5 - as I have been struggling to fix it in the past couple of days and it worked out, although it got a bit tricky.

I have added the following to /etc/openhab2/services/runtime.cfg

org.eclipse.smarthome.threadpool:thingHandler=50
org.eclipse.smarthome.threadpool:discovery=20
org.eclipse.smarthome.threadpool:safeCall=50
org.eclipse.smarthome.threadpool:ruleEngine=10

…but the number of threads did not actually increase, despite the change being reflected in the /var/lib/openhab2/config/org/eclipse/smarthome/threadpool.config file.

My /var/lib/openhab2/config/org/eclipse/smarthome/threadpool.config file contained the following lines by default as a fresh OH2.5 install (apart from the numbers):

:org.apache.felix.configadmin.revision:=L"13"
RuleEngine="10"
discovery="20"
safeCall="50"
service.pid="org.eclipse.smarthome.threadpool"
thingHandler="50"

…and it didn’t work, which was apparent both by general behaviour and by checking in the console (openhab-cli console) - it was only showing the same default 5 threads (and yes, it should show all of them even if they’re not in use, they just should be in the state TIMED_WAITING - it’s something else I didn’t know)
shell:threads --list |grep -i "ruleEngine"

Solution:
I had to change my /var/lib/openhab2/config/org/eclipse/smarthome/threadpool.config to this based on the suggestion from this GitHub thread - where the most important change is the change of the line from RuleEngine to ruleEngine:

:org.apache.felix.configadmin.revision:=L"17"
discovery="20"
org.quartz.threadPool.threadCount="20"
ruleEngine="10"
safeCall="50"
service.pid="org.eclipse.smarthome.threadpool"
thingHandler="50"

After startup the “Aspirin” now works perfectly, and additionally there’re 20 “openHAB-job-scheduler_Worker-” instances, which also helps (thanks to the line org.quartz.threadPool.threadCount=“20”).
I have also increased the thread count to 150 in the end in the ruleEngine parameter, my OpenHAB consumes 404 Mb of memory this way according to htop.

Please shut down OpenHAB completely, make the changes and restart it to make it work.

On the same note - in order to avoid Threads being overloaded on startup, try to make use of the “SystemStarting” switch as described here.
Additionally if you try to avoid rules with purely “changed” or “received update”, it helps a lot on startup as well. Use instead wherever possible

Itemname changed to 1

or

Itemname received update "true"

To me these are the things which worked - I’m running a system on a 4Gb RPI4 with 1213 items, 480 rules and 60 things with MySQL as persistence. Before my system took about 30 minutes to start up fully and now it takes 10 and there’re no error messages, no need to move/rename rules.

A big thanks to all the people who helped me to get to this solution and good luck to anyone who stumbles upon this topic in the future!

This is still way to long on an RPi 4. Do you have lots of primitives or unnecessary defining types in your Rules? The Rules parser has a really hard time with primitives and a somewhat harder time when you specify type unnecessarily. My theory is that when you do so the parser needs to do way more work at load time in order to ensure that that type is allowed in that context. At one point we were able to come up with one line of code that took several minutes to load on a fast Intel processor with plenty of RAM. When you avoid specifying type, those checks will wait for runtime vastly increasing your OH boot time.

As for editing the config file directly, I believe you can do this be creating /etc/openhab2/services/threadpool.cfg and populate it with those settings (don’t leave any out). That should cause OH to see the changes and overwrite threadpool.config with the changes.

The danger with editing the config file directly is that it’s an automatically generated file and it will become overwritten on the next upgrade of OH and you’ll have to make the change again.

I don’t know for certain that this will work but it’s worth a try. I’ll try it myself when I can get to my system.

With openhab 3.0’s removal of thread pooling, would it still be a bad idea to do a long (e.g. minutes) sleep or processing in a rule, assuming the system has a lot of memory (>= 16GB)

It depends on what you’re doing. During the long period, the rule cannot run again - but you can get more triggers queued up so that it executes again immediately after it’s finally finished. You can’t control that. Nor have you any way to cancel or abort the long wait.

To give a tl;dr to rossko57’s spot on reply, it’s less bad in OH 3. But it’s still not a great approach.

And there are rumblings of bringing back the thread pool so it would be best to avoid long sleeps where feasible.