Exemplo n.º 1
0
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 recorder to first place in load order
    if 'recorder' in load_order:
        load_order.promote('recorder')

    return load_order
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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 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')

    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)

    return load_order
Exemplo n.º 5
0
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 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')

    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)

    return load_order
Exemplo n.º 6
0
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())
Exemplo n.º 7
0
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())
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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
Exemplo n.º 11
0
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