Previous Item State not always working correctly

Currently running openHAB 3.2.0.M1 on a docker instance of a standalone Ubuntu 20.04 server and i’ve noticed some new behaviour. I’ve got a rule that triggers based on an item command. In the past I had simply used the item.state in addition to receivedCommand to compare the current vs new states. This stopped working in recent milestone builds (which i suspect that the item state isn’t guaranteed to still be the old state when using the received command trigger as I was). So I updated my rule to use item.previousState(false,“jdbc”).state. Even with this new setup I’ve noticed that there are errors sometimes. As you can see from my logging it appears that the JDBC driver is writing the new value just moments before the get hist request happens - therefore causing an incorrect return. It would appear that this is potentially a racecondition bug? Or am I missing something?

2021-09-01 18:32:43.728 [INFO ] [persistence.jdbc.internal.JdbcMapper] - JDBC::logTime: 'storeItemValue':
 afterAccess     = 26 ms
 timeAverage50  = 16 ms
 timeAverage100 = 15 ms
 timeAverage200 = 20 ms
 afterAccessMin  = 1 ms
 afterAccessMax  = 795 ms
 1000Statements = 0 sec
 statementCount = 165

2021-09-01 18:32:43.729 [INFO ] [persistence.jdbc.internal.JdbcMapper] - JDBC::logTime: 'getHistItemFilterQuery':
 afterAccess     = 17 ms
 timeAverage50  = 16 ms
 timeAverage100 = 15 ms
 timeAverage200 = 20 ms
 afterAccessMin  = 1 ms
 afterAccessMax  = 795 ms
 1000Statements = 0 sec
 statementCount = 166

2021-09-01 18:32:43.729 [INFO ] [org.openhab.core.model.script.MODE  ] - HennyHaus_Mode initiated mode change
2021-09-01 18:32:43.729 [INFO ] [org.openhab.core.model.script.MODE  ] - Triggered by mode command
2021-09-01 18:32:43.730 [INFO ] [org.openhab.core.model.script.MODE  ] - Current mode is: Evening
2021-09-01 18:32:43.730 [INFO ] [org.openhab.core.model.script.MODE  ] - New mode is: Evening

Well JDBC or not it isn’t transactionally safe so yes race conditions can happen, particularly if you access the previous state in a rule that triggers on that very same item to change.
That would not be a bug though as nobody promised this to be safe, so you as the programmer have to work around.
FWIW you can do item.persist() in a rule to ensure this happens before you proceed.

For completeness it also depends on your definition when writes into persistent storage happen so if you use a strategy like everyMinute in jdbc.persist that would be another explanation.

It’s completely predictable that this will fail, crops up regularly. Item states may or may not respond in some way to Item commands eventually, but
any response is totally asynchronous. This is a fundamental openHAB design feature, not a flaw.

Usually requires a bit of thinking about how to deal; if a rule is reliant on Item state, maybe trigger on state not command.

The most important cycle in openHAB -

a)  Item gets command (from rule or UI)
b)  Item passes command to binding
c)  binding passes to device
Note that Item state is not affected so far
d)  binding receives status from device
e)  binding/channel updates Item state

It sounds like your original rule was operating at the (b) point in the cycle, where reading the Item’s state is likely to get you the “old” state before the command takes effect.
It’s just luck though, all the timing of rule execution is running in parallel.

There is also openHAB’s autoupdate feature in the mix here. If your Item is linked to a real device, autoupdate will be having a speed-up effect. If your Item is freestanding, you may be reliant on autoupdate for any state change at all.
This is probably important in your rule design.

OK, I think we’ve established that the fact that it has worked up to this point has been some what of a fluke. That one of the things that makes timing problems so pernicious. So let’s explore what we can do about it.

As rossko57 suggests, if you can, moving to a changed trigger or even a received update trigger would be the most full proof. You’ll have implicit variables with the newState and previousState defined for you which are not dependent on timing what so ever. But that means you can’t react on the command itself. But does that really make sense here? We don’t have the rule so we can’t say. But usually if you care about the state of the Item, you will trigger based on received update or changed. A command is not guaranteed to result in an update to an Item.

Also as rossko57 suggests, consider turning off autoupdate. This Item appears to be one that is not linked to a Channel based on its name (which is about all we have to go on) so the only thing that is causing the Item to change state is autoupdate. Turn autoupdate off and you can update the Item’s state in your received command rule. With this configuration you can rely on item.state because the Item’s state won’t change in response to the command, it will retain the old state until you explicitly update it.

Maybe this rule could be split up into multiple rules with changed from X to Y type triggers. In that case the problem is solved in the triggers themselves. Especially with UI rules this approach can greatly simplify some rules. Though this too requires using a changed or received update trigger, not received command.

This appears to be driving a sort of state machine. Maybe the addition of some new states could address the issue.

The more I think about it the more it makes sense that I was just getting ‘lucky’ up until recently with it working the way it was. I really think I ultimately need to re-work what I am doing here to make things work smoother but for now I have turned off the auto update so hopefully that holds things over until I have some time to rework.

Thanks for all of the input on this one!