* Use defaultdict for registry indices
defaultdict is faster and does not have to create an empty
dict that gets throw away when the key is already present
* Use defaultdict for registry indices
defaultdict is faster and does not have to create an empty
dict that gets throw away when the key is already present
* Move thread safety check in entity_registry sooner
It turns out we have a lot of custom components that are writing
to the entity registry using the async APIs from threads. We now
catch it at the point async_fire is called. Instread we should check
sooner and use async_fire_internal so we catch the unsafe operation
before it can corrupt the registry.
* coverage
* Apply suggestions from code review
This function was only ever used in homekit, and since there is
now an index of devices in the entity registry, homekit no longer
uses it.
I searched github code for all references to async_get_device_class_lookup
and the only think I could find using it were forks of core. It seems
unlikely that any custom components are affected by removing this
function
* Add category registry
* Add entity registry support
* Update homeassistant/components/config/entity_registry.py
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
* Use ulid instead
* Add tests for adding same name in different scopes
* Handle keyerror on update
* Lookup tweak
* Omit categories from entity registry snapshots
* Use base registry
* Update snapshots
* Update snapshots
---------
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
We save the device and entity registry to disk quite often, and
the cost of serializing them to the storage can block the event
loop for >100ms. Add a cache to reduce the change the loop is blocked
at an inopportune time at run time. The first write after startup
will still be a little slow but we do have to serialize the
bulk of it at least once as there is no way to avoid this
```
2024-03-14 11:28:19.765 WARNING (MainThread) [homeassistant.helpers.storage] Writing data with data_func: core.device_registry
2024-03-14 11:28:20.020 WARNING (MainThread) [homeassistant.helpers.storage] Writing data with data_func: core.entity_registry
2024-03-14 11:28:20.178 WARNING (MainThread) [asyncio] Executing <TimerHandle cancelled when=2319925.760294916 Store._async_schedule_callback_delayed_write() created at /Users/bdraco/home-assistant/homeassistant/helpers/storage.py:328> took 0.159 seconds
```
There were a few places we were missing the set to list
conversions in the registries. We do this before its
cached to avoid the JSON serializer having to fallback
to the default method every time since its expensive
to switch back from the native code into python context
for every set.
Some of the data we had to search for was already available
in a dict or underlying data structure. Make it available
instead of having to build it every time.
There are more places these can be used, but I only did
the device registry cleanup for now
Avoid linear search to remove from entity registry index
Because the entity registry index needs to preserve insertion order
for backwards compat, a list was used for the index. Because some
config entries/devices/areas have a large amount of entities, removing
the entities, the O(n) time complexity of removing from a list can
slow down reloads. As python has no orderedset in stdlib, use
a dict since it preserves insertion order has O(1) add/remove
time complexity for the average case