Fix state overwrite race condition where two platforms request the same entity_id (#42151)
* Fix state overwrite race condition where two platforms request the same entity id * fix test * create reservations instead * revert * cannot use __slots__ because we patch async_all
This commit is contained in:
parent
bb641c23a9
commit
df2ede6522
7 changed files with 119 additions and 8 deletions
|
@ -973,6 +973,7 @@ class StateMachine:
|
|||
def __init__(self, bus: EventBus, loop: asyncio.events.AbstractEventLoop) -> None:
|
||||
"""Initialize state machine."""
|
||||
self._states: Dict[str, State] = {}
|
||||
self._reservations: Set[str] = set()
|
||||
self._bus = bus
|
||||
self._loop = loop
|
||||
|
||||
|
@ -1080,6 +1081,9 @@ class StateMachine:
|
|||
entity_id = entity_id.lower()
|
||||
old_state = self._states.pop(entity_id, None)
|
||||
|
||||
if entity_id in self._reservations:
|
||||
self._reservations.remove(entity_id)
|
||||
|
||||
if old_state is None:
|
||||
return False
|
||||
|
||||
|
@ -1116,6 +1120,29 @@ class StateMachine:
|
|||
context,
|
||||
).result()
|
||||
|
||||
@callback
|
||||
def async_reserve(self, entity_id: str) -> None:
|
||||
"""Reserve a state in the state machine for an entity being added.
|
||||
|
||||
This must not fire an event when the state is reserved.
|
||||
|
||||
This avoids a race condition where multiple entities with the same
|
||||
entity_id are added.
|
||||
"""
|
||||
entity_id = entity_id.lower()
|
||||
if entity_id in self._states or entity_id in self._reservations:
|
||||
raise HomeAssistantError(
|
||||
"async_reserve must not be called once the state is in the state machine."
|
||||
)
|
||||
|
||||
self._reservations.add(entity_id)
|
||||
|
||||
@callback
|
||||
def async_available(self, entity_id: str) -> bool:
|
||||
"""Check to see if an entity_id is available to be used."""
|
||||
entity_id = entity_id.lower()
|
||||
return entity_id not in self._states and entity_id not in self._reservations
|
||||
|
||||
@callback
|
||||
def async_set(
|
||||
self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue