Obviously a ReentrantLock causes some kind of deadlock in openhab 2.3, the rules are called but the locked area gets not executed.
At a fresh install/start (empty userdata) all is working fine. After 2 or 3 “docker restart openhub” somewhen this situation happens (docker start/stop seems to work better - more gracefully…?).
After the situation happend one, it does not goes away. Even a restart does not help. (I don’t understand why the ReentrantLock should be persitent?!). I have to delete the docker container and the userdata dir.
(I checked for the unlock. All rules have the same structure and there are no returns which could bypass the finally.)
#openhab.log
... [DEBUG] [ntime.internal.engine.RuleEngineImpl] - Executing startup rule 'updateLedR07'
... [ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'updateLedR07': Could not cast NULL to org.eclipse.smarthome.core.library.types.DecimalType; line 621, column 40, length 35
#comment: I don't understand, why this error not get logged by my own catch!?
...
... [DEBUG] [ntime.internal.engine.RuleEngineImpl] - Executing startup rule 'triggerHmrHeartbeat'
... [INFO ] [clipse.smarthome.model.script.rrinfo] - triggerHmrHeartbeat - in
... [INFO ] [clipse.smarthome.model.script.rrinfo] - triggerHmrHeartbeat - locked
... [INFO ] [clipse.smarthome.model.script.rrinfo] - triggerHmrHeartbeat - out: triggered
#comment: ok (function in and out)
...
... [DEBUG] [ntime.internal.engine.RuleEngineImpl] - Executing rule 'updateLedR05'
... [DEBUG] [ntime.internal.engine.RuleEngineImpl] - Executing rule 'updateLedR04'
...
... [DEBUG] [org.quartz.core.JobRunShell ] - Calling execute on job DEFAULT.led_status.rules#triggerHmrHeartbeat#36 * * * * ?
... [DEBUG] [ntime.internal.engine.ExecuteRuleJob] - Executing scheduled rule 'triggerHmrHeartbeat'
... [INFO ] [clipse.smarthome.model.script.rrinfo] - triggerHmrHeartbeat - in
#comment: obviously the ReentrantLock stays locked and so it gets not further!
My code looks like:
var java.util.concurrent.locks.ReentrantLock lockLedStatus = new java.util.concurrent.locks.ReentrantLock()
// 0 GREEN; 1 ORANGE; 2 nzw. sonst RED
val Functions$Function2<StringItem, Integer, String> setLedStatus =
[ StringItem itemLed, Integer stateWindows |
try {
val String logClass = "rrinfo"
val String logKey = "setLedStatus - "
if (itemLed != NULL) {
//logKey = logKey + itemLed.name
//! LED-Statusanzeige (16-fach): HM-OU-LED16: 0 aus; 1 rot; 2 grün; 3 orange
var String stateOut = "RED";
if ( stateWindows == 0) {
stateOut = "GREEN";
} else if ( stateWindows == 1) {
stateOut = "ORANGE";
}
// Test: Verzögerung,wegen Anzeige-Problemen (überlagerte Kommunikation im Homematic-System)
//Thread::sleep(30)
//var String stateCurrent = itemLed.state.toString
//if (stateCurrent == stateOut) {
//logDebug(logClass, logKey + " - no change == " + stateOut)
//} else {
itemLed.sendCommand(stateOut)
// stateOut = stateCurrent + " => " + stateOut
//}
return stateOut
}
else {
logDebug(logClass, logKey + " itemLed is NULL!")
return "ERROR"
}
}
catch (Throwable t) {
logError(logClass, logKey + t.toString)
return "ERROR"
}
]
rule updateLedR07
when
System started
or Item hmLightTerrace changed
or Time cron "23 */5 * * * ?"
then
val String logClass = "rrinfo"
val String logKey = "updateLedR07 - "
try {
lockLedStatus.lock()
var Integer stateWindows = 0
try {
var Integer valueDimmer = (hmLightTerrace.state as DecimalType).intValue()
if (valueDimmer > 0) stateWindows = 2
} catch (Throwable t) {
logError(logClass, logKey + t.toString)
stateWindows = 0
}
var String result = setLedStatus.apply(hmLedHall15, stateWindows)
logDebug(logClass, logKey + "out: " + result)
}
catch (Throwable t) {
logError(logClass, logKey + t.toString)
}
finally {
lockLedStatus.unlock()
}
end
rule triggerHmrHeartbeat
when
Time cron "36 * * * * ?"
or System started
then
val String logClass = "rrinfo"
val String logKey = "triggerHmrHeartbeat - "
try {
logInfo(logClass, logKey + "in")
lockLedStatus.lock()
logInfo(logClass, logKey + "locked")
hmrHeartBeat.sendCommand("ON")
setLedStatus.apply(hmLedHall16, 0)
logInfo(logClass, logKey + "out: triggered")
}
catch (Throwable t) {
logError(logClass, logKey + t.toString)
}
finally {
lockLedStatus.unlock()
}
end