def _load_order_component(comp_name, load_order, loading): """ Recursive function to get load order of components. """ component = get_component(comp_name) # if None it does not exist, error already thrown by get_component if component is None: return OrderedSet() loading.add(comp_name) for dependency in component.DEPENDENCIES: # Check not already loaded if dependency not in load_order: # If we are already loading it, we have a circular dependency if dependency in loading: _LOGGER.error('Circular dependency detected: %s -> %s', comp_name, dependency) return OrderedSet() dep_load_order = _load_order_component(dependency, load_order, loading) # length == 0 means error loading dependency or children if len(dep_load_order) == 0: _LOGGER.error('Error loading %s dependency: %s', comp_name, dependency) return OrderedSet() load_order.update(dep_load_order) load_order.add(comp_name) loading.remove(comp_name) return load_order
def load_order_component(comp_name): """ Returns an OrderedSet of components in the correct order of loading. Raises HomeAssistantError if a circular dependency is detected. Returns an empty list if component could not be loaded. """ return _load_order_component(comp_name, OrderedSet(), set())
def load_order_components(components): """ Takes in a list of components we want to load: - filters out components we cannot load - filters out components that have invalid/circular dependencies - Will make sure the recorder component is loaded first - Will ensure that all components that do not directly depend on the group component will be loaded before the group component. - returns an OrderedSet load order. """ _check_prepared() group = get_component('group') recorder = get_component('recorder') load_order = OrderedSet() # Sort the list of modules on if they depend on group component or not. # We do this because the components that do not depend on the group # component usually set up states that the group component requires to be # created before it can group them. # This does not matter in the future if we can setup groups without the # states existing yet. for comp_load_order in sorted( (load_order_component(component) for component in components), # Test if group component exists in case # above get_component call had an error. key=lambda order: group and group.DOMAIN in order): load_order.update(comp_load_order) # Push recorder to first place in load order if recorder.DOMAIN in load_order: load_order.promote(recorder.DOMAIN) return load_order
def load_order_components(components): """ Takes in a list of components we want to load: - filters out components we cannot load - filters out components that have invalid/circular dependencies - Will make sure the recorder component is loaded first - Will ensure that all components that do not directly depend on the group component will be loaded before the group component. - returns an OrderedSet load order. """ _check_prepared() load_order = OrderedSet() # Sort the list of modules on if they depend on group component or not. # Components that do not depend on the group usually set up states. # Components that depend on group usually use states in their setup. for comp_load_order in sorted((load_order_component(component) for component in components), key=lambda order: 'group' in order): load_order.update(comp_load_order) # Push some to first place in load order for comp in ('recorder', 'introduction'): if comp in load_order: load_order.promote(comp) return load_order
def load_order_components(components: Sequence[str]) -> OrderedSet: """Take in a list of components we want to load. - filters out components we cannot load - filters out components that have invalid/circular dependencies - Will make sure the recorder component is loaded first - Will ensure that all components that do not directly depend on the group component will be loaded before the group component. - returns an OrderedSet load order. - Makes sure MQTT eventstream is available for publish before components start updating states. Async friendly. """ _check_prepared() load_order = OrderedSet() # Sort the list of modules on if they depend on group component or not. # Components that do not depend on the group usually set up states. # Components that depend on group usually use states in their setup. for comp_load_order in sorted( (load_order_component(component) for component in components), key=lambda order: 'group' in order): load_order.update(comp_load_order) # Push some to first place in load order for comp in ('mqtt_eventstream', 'mqtt', 'logger', 'recorder', 'introduction'): if comp in load_order: load_order.promote(comp) return load_order
def _load_order_component( hass, # type: HomeAssistant comp_name: str, load_order: OrderedSet, loading: Set) -> OrderedSet: """Recursive function to get load order of components. Async friendly. """ component = get_component(hass, comp_name) # If None it does not exist, error already thrown by get_component. if component is None: return OrderedSet() loading.add(comp_name) for dependency in getattr(component, 'DEPENDENCIES', []): # Check not already loaded if dependency in load_order: continue # If we are already loading it, we have a circular dependency. if dependency in loading: _LOGGER.error("Circular dependency detected: %s -> %s", comp_name, dependency) return OrderedSet() dep_load_order = _load_order_component(hass, dependency, load_order, loading) # length == 0 means error loading dependency or children if not dep_load_order: _LOGGER.error("Error loading %s dependency: %s", comp_name, dependency) return OrderedSet() load_order.update(dep_load_order) load_order.add(comp_name) loading.remove(comp_name) return load_order
def load_order_component(hass, # type: HomeAssistant comp_name: str) -> OrderedSet: """Return an OrderedSet of components in the correct order of loading. Raises HomeAssistantError if a circular dependency is detected. Returns an empty list if component could not be loaded. Async friendly. """ return _load_order_component(hass, comp_name, OrderedSet(), set())