Add an asyncio Lock around pairing, which cant be used concurrently #21933
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description:
I'll need to rebase this after #21901 is merged to fix a conflict in the
update()
method.I was recently discussing plans for homekit_controller with another user/contributor and realised that there is no explicit locking around the pairing. The homekit_controller Pairing object is not safe to use concurrently, so users with bridges may be experiencing glitches as the asynchronicity trips up the session encryption.
I think there is already some logic around EntityPlatforms that limits concurrent polls (
PARALLEL_UPDATES
) which means you are unlikely to see problems with just polling. However if you have concurrent writes (or a write and poll at the same time) then you'll get a AccessoryDisconnected error and the request will fail. In one of my longer running branches to add BLE homekit support I actually noticed this quite a lot with even a single device. BLE requests are quite slow so multi tapping on UI elements was enough to trigger the problem.It seemed like it would be easiest to reason about this if we used the async_ version of the entity API as much as possible and handled the locking needed for the pairing object on the HA side as close to the pairing object as possible. I also wanted an approach that played well with future plans to make an asyncio variant of homekit_python (the upstream we are using for this component).
I have tested this with a homekit_python demoserver.py setup as a fake bridge that has 50 fake light bulbs attached to it, and the tests pass locally.
As I was editing an adjacent function i've removed
update_characteristics
as its no longer used.Checklist:
tox
. Your PR cannot be merged unless tests pass