Disclaimer: this app is for advanced usage of Homey! For basic home automations you propably don’t need this
Concurrency is the ability to run different applications in parallel and handle resources appropriately. Homey for example allows you to run multiple flows at once but it does not ensure that a specific resource (i.e. a logic variable) is accessed only once at a time. This can be problematic and can cause so named racing conditions.
A semaphore is a well known principle to prevent such issues as they ensure a resource is accessed only once at a time. This app provides such an semaphore for your Homey and enables more powerful automations.
Let’s consider the following scenario: you have 3 flows that all get triggered by the same event (i.e. a button press). Furthermore there is an logic variable initialized with the value of 0. Let’s assume that every flow will calculate the value of the variable as +=1. As result you would expect the variable to be 3 after all the flows have completed, but in reality you will find that it has always a different value!
The reason for that is that we have a racing condition here. The operation of getting the variable, increasing it and writing it back to the memory is not atomic. Therefore it can be that multiple flows operate on the same variable at the same time. For example you would have this:
flow 1 reads the variable into the memory (0)
flow 2 reads the variable into the memory (0)
flow 1 increase the value and writes the variable back to memory (1)
flow 2 increase the value and writes the variable back to memory (1)
To prevent this behaviour we need to ensure that only one flow at the time is reading the variable, increasing it and writing it back.
To do so we need a semaphore:
in the condition of the 3 flows add the ‘Wait until the semaphore is unlocked’ flow card
in the action of the 3 flows add the ‘Unlock the semaphore’ flow card after the calculation
Now the following will happen:
the first flow that checks the condition will lock the semaphore
whenever one of the other flows comes to check the condition it will wait and not continue for the moment (usually we are talking about milliseconds here)
the first flow card will do it’s calculation and once this is done it will unlock the semaphore
the next flow card that is waiting can now continue etc. until all work is done!
The semaphore does not lock at a specific variable and it is also not tied to a variable at all. You can just ensure that while you lock the semaphore that no other flow enters this “critical” section. Currently there is also just one sempaphore at the time.
Regarding the installation issue: are you using homey v4.x?
Interesting idea One question: if you release the semaphore in an action card, and action cards are started concurrently (as they are), how can you ensure that the calculation is protected by the semaphore? It seems to me there’s still a race condition between the semaphore being released and the calculation finishing.
I’d also be interested to learn how the semaphore in implemented in the app
Yep I’m using the 4.xx firmware. So it’s only available to 5.0?
Still interesting app and have to say “out of the ordinary” idea. I never thought this could be possible in an app, but only in Homey “core functions”. Have to wait for the stable 5.0 release to test it.
Presently I only have an issue with multiple zwave or zigbee actions running concurrently. I have solved this in the past with wait times (e.g. first action with 0 delay, second action with 1 second delay etc.).
I still have hopes that the concurrent activity issue on zwave and zigbee is solved with V5.0 of the firmware.
I’ll be sure to check out your semaphore should v5 nog solve my issues.
Yes and no;) It actually should be working for 4.x too but there is a bug in homey wich is solved in v5.0. Actually I thought it should work on v4.x but if this is really not the case I’ll update the app