Yep. This is exactly what I’m talking about. Experiment with the sleep time to find the smallest value that works reliably.
I usually do the spacing a bit different but I think it won’t matter functionally.
gCHSchedule.members.forEach[ item |
The DP is more than just a reentrant lock. The reentrant lock provides the locking mechanism to prevent more than one instance of the Rule from actively running at the same time. But what you do inside the locked part of the Rule is also important. In this case you will want to capture the all the states that you can before the lock but not run the findFirst until after acquiring the lock. Then you would add a small Thread::sleep at the end just before unlocking to give the Item Registry a chance to finish updating the Group.
I’m always hesitant to suggest this approach because, in the 30 Item example, if they all update at the same time and you have a sleep of 100 msecs it will take 2.5 seconds before ANY other Rules will be able to run. So if you have other Rules in your system where a 2.5 second delay between the Rule trigger and the Rule execution occurs you will have only traded one problem for another.
There is a way to increase the Thread pool (I think it is one of the files in userdata/etc) so if you do go down the gatekeeper route, you will probably want to increase that from 5 to 35. It will increase the amount of required RAM significantly so that might not be a good option if you are on an RPi. You will have to experiment to find the largest number of threads in the pool that will fit in your available RAM.
You will also have to go and change it back everytime you upgrade OH.