Commit 765a22d5 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Device component:

- Implemented Topological Sort of sub_devices to prevent inserting a sub-device before its controller in multi-controller hierarchies
parent 87c9a247
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
# limitations under the License.

import grpc, logging, os, time
from typing import Dict
from typing import Dict, List
from prometheus_client import Histogram
from common.Constants import ServiceNameEnum
from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name
@@ -109,6 +109,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
            # (which controller is in charge of which sub-device).
            new_sub_devices : Dict[str, Device] = dict()
            new_sub_links : Dict[str, Link] = dict()
            sorted_sub_device_uuids : List[str] = list()

            #----- Experimental ------------
            new_optical_configs : Dict[str, OpticalConfig] = dict()
@@ -117,8 +118,8 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
                t5 = time.time()
                # created from request, populate endpoints using driver
                errors.extend(populate_endpoints(
                    device, driver, self.monitoring_loops, new_sub_devices, new_sub_links,
                    new_optical_configs
                    device, driver, self.monitoring_loops, new_sub_devices, sorted_sub_device_uuids,
                    new_sub_links, new_optical_configs
                ))
                t6 = time.time()
                t_pop_endpoints = t6 - t5
@@ -165,7 +166,8 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):

            t10 = time.time()

            for sub_device in new_sub_devices.values():
            for sub_device_uuid in sorted_sub_device_uuids:
                sub_device = new_sub_devices[sub_device_uuid]
                context_client.SetDevice(sub_device)

            t11 = time.time()
+21 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
# limitations under the License.

import json, logging, re
from graphlib import TopologicalSorter, CycleError
from typing import Any, Dict, List, Optional, Set, Tuple, Union
from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME
from common.DeviceTypes import DeviceTypeEnum
@@ -104,8 +105,8 @@ def get_device_controller_uuid(device : Device) -> Optional[str]:

def populate_endpoints(
    device : Device, driver : _Driver, monitoring_loops : MonitoringLoops,
    new_sub_devices : Dict[str, Device], new_sub_links : Dict[str, Link],
    new_optical_configs : Dict[str, OpticalConfig]
    new_sub_devices : Dict[str, Device], sorted_sub_device_uuids : List[str],
    new_sub_links : Dict[str, Link], new_optical_configs : Dict[str, OpticalConfig]
) -> List[str]:
    device_uuid = device.device_id.device_uuid.uuid
    device_name = device.name
@@ -293,6 +294,24 @@ def populate_endpoints(
            errors.append(ERROR_UNSUP_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data)))
            continue

    # Topologically sort new_sub_devices so that controllers (those referenced by other
    # devices via their controller_id) come before the devices that depend on them.
    graph : Dict[str, Set[str]] = dict()
    for dev_uuid, sub_device in new_sub_devices.items():
        predecesors = graph.setdefault(dev_uuid, set())
        ctrl_uuid = get_device_controller_uuid(sub_device)
        if ctrl_uuid is None: continue
        predecesors.add(ctrl_uuid)

    try:
        ts = TopologicalSorter(graph)
        sorted_sub_device_uuids.extend(list(ts.static_order()))
    except CycleError:
        MSG = 'Topological sort failed due to cycle among sub-devices({:s}), graph({:s})'
        msg = MSG.format(str(new_sub_devices), str(graph))
        LOGGER.exception(msg)
        errors.append(msg)

    return errors

def populate_endpoint_monitoring_resources(device_with_uuids : Device, monitoring_loops : MonitoringLoops) -> None: